1.为什么要有继承关系
复用是编程中很重要且不可或缺的一部分,可以帮我们很好地避免“重复造轮子”的问题,提高我们的编码效率,而继承关系可以让我们要增加的对象去继承已有对象的属性和方法,从而实现复用。
2.继承关系的通俗理解
与现实中我们正常理解的继承不同,面向对象继承中的继承中人类更类似于父类的强化体,在武侠小说中我们经常看到“打了小的,出来老的”的桥段,在面向对象中恰恰相反,父类会的子类全部都会,子类却可以拥有父类所不具备的能力,颇有“长江后浪推前浪,一代更比一代强”的风采。
3.继承的LSP原则
任何行为肯定有它的准则,就像是我们现实中要进行财产继承也要遵循一定的法律条款。在继承关系中我们要遵循的Liskov Substitution Principle(LSP)原则,是由一位名叫Barbara Liskov的女科学家提出的。该原则主要包含下面的内容
-
子类型可以增加方法,但不可删方法
-
子类型需要实现抽象类型中的所有未实现的方法
-
子类型中重写的方法必须有相同类型的返回值或者符合co-variance的返回值
-
子类型中重写的方法必须使用同样类型的参数或者符合contra-variance的参数
-
子类型中重写的方法不能抛出额外的异常,抛出相同的或者符合co-variance的异常
这样看起来似乎有些抽象,没关系,我们接下来进行通俗的理解。
对于第一条可以理解成我教给你的东西你都要学会,这样才能做到父类可以出场的场合子类也能出场嘛。
第二条就理解成虽然父类没有这个东西,但他吹出去(声明)了他有,所以你作为后人,父债子偿吗,得把你的父辈吹出去的牛给实现了。
第三条和第四条可以合起来理解成你不仅要实现,还要按照你爸吹的方式一字不漏的实现,就好比你爸吹你数学考第一,那你英语考第一也没用。
第五条是强调你爸处理得了的情况你都要能处理,很好理解嘛,你爸能做的你也要能做,不然就有些学艺不精的意思。
综上来看我们可以得出一个结论:儿子不好当啊。但没办法,为了继承父类的“财产”,也只能忍忍了。
4.co-variance和contra-variance
现在对co-variance和contra-variance进行解释,co-variance翻译过来叫协变,specific越来越具体,contra-variance是逆变,specific越来越抽象。看起来这两个概念属实很抽象。在进行一个通俗的理解。把父类传给子类的方法比作武功,我们不仅要学会父辈的武功,还要提升父辈的武功,突出一个父辈做不了的事情我能做。
5.总结
实际中我们也不用记那么多规则,就记住“父无子有,父有子精”,父类能做的事子类一定能做,甚至能做得更好。