“父类引用”——>“子类对象”,第一次听到这个短语还是在学C#课堂上。当时就感觉到困惑,按照中国的传统思维方式,子类可以继承父类的“财产”,难道还可以反着来?之前也做过这方面的总结,但都太过于严肃,这次尽量不用代码,用比较生动的方式便于记忆。
一、为什么要父类引用指向子类对象?
父类引用指向子类对象,也有人说这是面向接口编程,可以降低程序的耦合性,即调用者不必关心调用的是哪个对象,只需要针对接口编程就可以了,被调用者对于调用者是完全透明的。让你更关注父类能做什么,而不去关心子类是具体怎么做的,你可以随时替换一个子类,也就是随时替换一个具体实现,而不用修改其他。
假设一个家有四口人(爸爸、妈妈、儿子、女儿),一天妈妈让爸爸去买水果,爸爸今天工作很累,给钱让孩子去买,并交代不要告诉妈妈。买水果这件事爸爸也能做,但他这个任务交给了孩子(即父类引用指向子类对象)。爸爸不关心孩子是走去买还是打车去买(可能儿子想走着去,省下打车钱买巧乐兹;而女儿怕晒,选择打车去),具体这个任务是走着去完成还是打车去完成,替换一下这个任务的执行者就可以,爸爸不需要做其他的修改。
二、父类引用指向子类对象有什么特点?
可以用这几个关键词来概括:多态、动态链接,向上转型
多态是面向对象编程的三大特征之一。从一定角度来看,前两大特征(封装、继承)几乎都是在为多态做准备。一个有趣但不严谨的说法是:继承是子类使用父类的方法,而多态则是父类使用子类的方法。
沿用上面买水果的例子,儿子走着去买水果,女儿打车去买水果,爸爸自己开车去买水果。现在爸爸把这个买水果的任务交给孩子,孩子覆盖了爸爸买水果的方法,有走着、有打车多种形式(即多态)
妈妈说让男生去买,此时执行买水果这个任务有一个条件(男性),那么调用的就是儿子走着去买水果(即动态链接)
完成买水果任务的是孩子,但妈妈的角度来看,以为是爸爸(即向上转型)
三、总结
使用父类类型的引用指向子类的对象
1、该引用只能调用父类中定义的方法和变量;
2、如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法;(动态连接、动态调用)
3、变量不能被重写(覆盖),“重写”的概念只针对方法,如果在子类中”重写“了父类中的变量,那么在编译时会报错。
(版权所有@JosephLin)