继承
当多个类型具有相同的成员时,可以使用继承来少写代码。
继承语法为:类型名+冒号+被继承的类型名。
class 英雄
{
public int hp;
}
class 艾希 : 英雄
{
public void 万箭齐发(英雄 目标)
{
目标.hp -= 100;
}
}
class 盖伦 : 英雄
{
public void 致死打击(英雄 目标)
{
目标.hp -= 20;
}
}
class 瑞兹 : 英雄
{
public void 法术涌动(英雄 目标)
{
目标.hp -= 40;
}
}
继承链
考虑以下继承关系:宝可梦->皮丘->皮卡丘->雷丘
如果直接继承的基类型也有他的直接继承类。
这样构成的链式继承关系,称为继承链。
当我们说继承关系时,说的是整个继承链上的类,而不是单指类的直接基类。
例如:
左边三个类都是雷丘的基类。
右边三个类都是宝可梦的派生类。
继承的限制
- 静态类不允许继承
- 结构不允许继承
- 继承链不能成环
- 只能指定一个直接基类进行继承
多态
继承的意义在于,派生类是完整的基类,具有基类的一切功能,可以当作基类使用。
也就是说,派生类的值可以赋值给基类类型的变量。
英雄 a = new 艾希();//可以直接声明
瑞兹 b = new 瑞兹();
英雄 c = b;//也可以用已有的变量进行赋值
这在我们的函数体中没有用。因为我们声明一个盖伦变量,当然是因为想用盖伦的专有成员。
但是,如果是作为函数的参数很有用。函数的参数也是声明变量。
这导致在调用函数时,可以使用派生类型的值,作为参数传递进去。
艾希 Ashe = new 艾希();
瑞兹 Ryze = new 瑞兹();
盖伦 Galen = new 盖伦();
Ashe.万箭齐发(Ashe);
Ashe.万箭齐发(Ryze);
Ashe.万箭齐发(Galen);
Ryze.法术涌动(Ashe);
Ryze.法术涌动(Ryze);
Ryze.法术涌动(Galen);
Galen.致死打击(Ashe);
Galen.致死打击(Ryze);
Galen.致死打击(Galen);
不使用多态的结果
如果上述例子中不使用多态和继承,那么代码会是下面这样:
class 艾希
{
public int hp;
public void 万箭齐发(艾希 目标)
{
目标.hp -= 100;
}
public void 万箭齐发(盖伦 目标)
{
目标.hp -= 100;
}
public void 万箭齐发(瑞兹 目标)
{
目标.hp -= 100;
}
}
class 盖伦
{
public int hp;
public void 致死打击(艾希 目标)
{
目标.hp -= 20;
}
public void 致死打击(盖伦 目标)
{
目标.hp -= 20;
}
public void 致死打击(瑞兹 目标)
{
目标.hp -= 20;
}
}
class 瑞兹
{
public int hp;
public void 法术涌动(艾希 目标)
{
目标.hp -= 40;
}
public void 法术涌动(盖伦 目标)
{
目标.hp -= 40;
}
public void 法术涌动(瑞兹 目标)
{
目标.hp -= 40;
}
}
艾希类存在的意义,是因为他会技能万箭齐发。
可是他们三个的技能效果只是造成伤害,只需要访问你的hp字段就行了。 不关心你是否会万箭齐发。
同理,在他们的技能对盖伦和瑞兹造成伤害时,也不关心他们有什么技能,只关心他们的hp。
为什么使用多态
c#中的功能存在的意义,都可以用四个角度去思考。
- 语法糖:这个语法是不是有替代方案。如果有,那现在这种语法是不是比替代方案更方便,或是更安全。如果是的话,那么这个功能就是语法糖。例如属性,索引器。
- 多数量:你知道该怎么写了,但全部手写出来会死人。程序就是为了省人手而生的,如果反而要人断手,理念就很冲突了。数组,循环,函数都是考虑这个问题的。
- 不可预知:你现在看到的程序并不是这个程序的完全体。一个程序总是会需要扩展,变动的。如果每次变动都需要变动当前的程序,那结果是不可想象的。变量,选择都是这方面的例子。
- 限制使用者:一个程序的安全运行,必须在一定条件下。为了维护这个条件,不能让使用者想做什么就做什么。访问权限,密封,就是干这个的。
继承这个语法,一定程度实现了第2点的意义。但这不是重点,他的存在就是为多态服务的。
有了继承才能保证多态的实现。
而多态的意义,占了第2点第3点。
数量从上面的例子看到了,仅仅3个类就声明了9个重载。如果换成宝可梦,上万种类型,后果不堪设想。
而不可预知,你使用多态声明的方法都可以给后续的类型使用。即便你现在没有拿到那些类型,你不知道那里面有什么东西。你的方法也可以生效。当然,他们需要使用继承是他们的事。看到现在的难度比预知未来的难度小多了。