我们都知道在面向对象的语言中,继承是必不可少的,那么它的优点是哪些呢?引用书上一段话吧!
(5)
提高产品或项目的开放性。
既然有了优点就应该有缺点:
C#与C++不同,不支持多重继承(即一个类从多个直接基类派生)。那么这里就引出了里氏替换原则。
但是这里我们需要注意的是:有子类出现的地方,父类未必就能适应。
前面我们引出了里氏替换原则的概念,通过这些概念我们可以了解到里氏替换原则为良好的继承定义了一个规范。这里就包含了4层含义:
《设计模式之禅》这本书上的例子,我个人感觉比较有意思,所以自己就直接把书上的例子分享给大家学习吧!呵呵~~
书上引用的是CS打枪游戏例子,这里把枪的类图列出:
abstract
class AbstractGun
{
//
射击
public abstract void shoot();
}
手枪,步枪,机枪的实现类源代码:
class
Handgun:AbstractGun
{
public override void shoot()
{
Console.WriteLine("
手枪射击
"
);
}
}
class
Rifle:AbstractGun
{
public override void shoot()
{
Console.WriteLine("
步枪射击
"
);
}
}
class
MachineGun:AbstractGun
{
public override void shoot()
{
Console.WriteLine("
机枪扫射
"
);
}
}
下面我们来定义一个士兵来使用这些枪吧!代码如下:
class
Program
{
static void Main(string[] args)
{
//
产生个士兵
Soldier soldier = new Soldier();
//
给士兵一支枪
soldier.setGun(new Handgun());
soldier.killEnemy();
System.Threading.Thread.Sleep(5000);
}
}
在这个程序中,在编写程序时Solider士兵类根本不用知道是哪个型号的枪(子类)被传入。
class
ToyGun:AbstractGun
{
//
仿真枪是不能射击的只能虚构一个了。
public override void shoot()
{
}
}
class
Program
{
static void Main(string[] args)
{
//
产生一个士兵
Solder soldier = new Solder();
soldier.setGun(new ToyGun());
soldier.killEnemy();
System.Threading.Thread.Sleep(5000);
}
}
大家都知道C#的三大特性:继承,封装,多态。继承就是告诉我们拥有父类的方法和属性,然后我们就可以重写父类的方法。那么按照继承原则,我们定义的仿真枪继承AbstractGun是没有问题的。但是我们在具体应用场景中就要考虑这个问题:子类是否能够完整地实现父类的业务。
2
,子类可以有自己的个性
class
AUG:Rifle
{
public void zoomout()
{
}
public override void shoot()
{
Console.WriteLine("AUG
射击
"
); ;
}
}
狙击手的源代码如下:
class
Sniper
{
private AUG aug;
public void setGun(AUG _aug)
{
this.aug = _aug;
}
public void killEnemy()
{
aug.zoomout();
//
开始射击
aug.shoot();
}
}
那么如何让狙击手使用AUG杀死人呢?
static
void Main(string[] args)
{
Sniper sniper = new Sniper();
sniper.setGun(new AUG());
sniper.killEnemy();
System.Threading.Thread.Sleep(5000);
}
static
void Main(string[] args)
{
Sniper sniper = new Sniper();
sniper.setGun((AUG)(new Rifle()));
sniper.killEnemy();
System.Threading.Thread.Sleep(5000);
}