开闭原则与里氏代换原则实验UML图及编程实现C#.docx
《开闭原则与里氏代换原则实验UML图及编程实现C#.docx》由会员分享,可在线阅读,更多相关《开闭原则与里氏代换原则实验UML图及编程实现C#.docx(8页珍藏版)》请在冰豆网上搜索。
![开闭原则与里氏代换原则实验UML图及编程实现C#.docx](https://file1.bdocx.com/fileroot1/2023-1/24/3996cdb2-28a2-4309-ae1d-87a7e3fe4cda/3996cdb2-28a2-4309-ae1d-87a7e3fe4cda1.gif)
开闭原则与里氏代换原则实验UML图及编程实现C#
实验2开闭原则与里氏代换原则综合训练
一、实验目的:
加深对开闭原则与里氏代换原则的理解
二、实验环境:
C#.Net
三、实验内容:
1、问题
(一)“长方形和正方形“思辨题:
最早来自于C++和Smalltalk领域。
正方形是否是长方形的子类的问题,西方一个很著名的思辨题。
试写一个求面积与周长的解决方案,要求画UML图并编程实现,并体现出开闭原则与里氏代换原则。
提示:
长方形类:
两个属性,宽度和高度;
正方形类:
一个属性,边。
1、UML类图如下:
2、运用的设计原则:
开闭原则:
一个软件实体应当对扩展开放,对修改关闭。
定义一个抽象类Stringle类,抽象类中有求面积和周长的函数,当想再次扩展求圆、菱形等的面积,继承抽象类,实现其功能,很方便就对其进行扩展。
里氏代换原则:
所有引用基类(父类)的地方必须能透明地使用其子类的对象。
Stringle类为基类,Square类和Rectangular为其子类,在引用基类的地方就能使用子类实现,代码如下。
3、C#实现代码如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
namespaceConsoleApplication1
{
classProgram
{
staticvoidMain(string[]args)
{
Stringlesquare=newSquare(5);
Stringlerectangular=newRectangular(3,5);
Accounteraccounter=newAccounter();
accounter.calculate(square);
accounter.calculate(rectangular);
Console.ReadLine();
}
}
publicclassAccounter
{
publicAccounter(){}
publicvoidcalculate(Stringlestringle)
{
stringle.Area();
stringle.ZhouChang();
}
}
///
///抽象类,定义了求面积和周长的方法,没有实现
///
publicabstractclassStringle
{
publicabstractvoidArea();
publicabstractvoidZhouChang();
}
///
///正方形类继承自抽象类
///
publicclassSquare:
Stringle
{
intwidth;
publicSquare(intw)
{
width=w;
}
publicoverridevoidArea()
{
intarea=width*width;
Console.WriteLine("正方形的面积为:
"+area);
}
publicoverridevoidZhouChang()
{
intscircle=width*4;
Console.WriteLine("正方形的周长为:
"+scircle);
}
}
///
///长方形类继承自抽象类
///
publicclassRectangular:
Stringle
{
intwidth;
intheight;
publicRectangular(intw,inth)
{
width=w;
height=h;
}
publicoverridevoidArea()
{
intarea=width*height;
Console.WriteLine("长方形的面积为:
"+area);
}
publicoverridevoidZhouChang()
{
intscircle=width*2+height*2;
Console.WriteLine("长方形的周长为:
"+scircle);
}
}
}
4、实验结果:
2、问题
(二)“士兵用枪杀敌”UML图理解与编程实现
(1)CS游戏中的枪械类图
(2)如果我们有一个玩具手枪,该如何定义呢?
先在上图增加一个类ToyGun,然后继承于AbstractGun类
(3)玩具枪与真实枪分离的类图
用C#实现代码如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
namespaceConsoleApplicationGun
{
classProgram
{
staticvoidMain(string[]args)
{
AbstractGunhandgun=newHandGun();//手枪
AbstractGunriflegun=newRifleGun();//步枪
AbstractGunmachinegun=newMachineGun();//机枪
AbstractGuntoygun=newToyGun();//
//AbstractToytoygun=newToyGun();//
Soldiersoldier=newSoldier();
soldier.killEnemy(handgun);//士兵拿手枪杀敌人
soldier.killEnemy(riflegun);//士兵拿步枪杀敌人
soldier.killEnemy(machinegun);//士兵拿机枪杀敌人
soldier.killEnemy(toygun);//士兵拿玩具枪杀敌人
}
}
publicclassSoldier
{
publicSoldier(){}
publicvoidkillEnemy(AbstractGunabstractgun)
{
abstractgun.shoot();
}
}
publicabstractclassAbstractGun
{
publicAbstractGun(){}
publicabstractvoidshoot();
}
publicabstractclassAbstractToy
{
publicAbstractToy(){}
publicabstractvoidshoot();
}
publicclassHandGun:
AbstractGun
{
publicHandGun(){}
publicoverridevoidshoot()
{
Console.WriteLine("Handgunshoot!
");
}
}
publicclassRifleGun:
AbstractGun
{
publicRifleGun(){}
publicoverridevoidshoot()
{
Console.WriteLine("RifleGunshoot!
");
}
}
publicclassMachineGun:
AbstractGun
{
publicMachineGun(){}
publicoverridevoidshoot()
{
Console.WriteLine("MachineGunshoot!
");
}
}
publicclassToyGun:
AbstractGun
{
publicToyGun(){}
publicoverridevoidshoot()
{
Console.WriteLine("ToyGunshoot!
");
}
}
}
实验结果: