Java的多态为何可以由子类实例化父类( 四 )



■网友
instance field(类成员属性) 跟 method (类成员方法)两者是有区别的,我们分开来说。对于当前讨论的场景,我们只考虑method即可。
引用接受对象父类用的方法,它的任意一个子类肯定都是有的,而子类独特的方法对于父类的引用来说,它是不知道也是不care的。父类引用无论指向的是父类的对象还是子类的对象,它只会说,我不管你有多少个方法,但是定义在我身上的那几个方法,我随时可能会调用,你能保证有就行,所以父类的引用是答应接受子类的对象的。而反过来不行,子类的引用绝不会答应。
这就是所谓的里氏代换原则.
引用执行方法调用当父类的引用要执行方法1的时候,他只会跟他指向的对象说,“嗨,哥们,执行一下你的方法1”然后他就不管了,继续睡大觉去了。然后真实的对象实例就会低头看看写在自己身上的方法1,捏出来执行一把。这个时候如果子类对象重写了方法1,捏出来的就是重写的方法。如果没重写,就会找他爸,从他爸身上去捏方法1出来。
这就是所谓的动态绑定。

成员属性的特别之处如果父类、子类定义了相同名字的成员属性,那么这两者是同时存在的。
比如,都定义了age属性,父类初始化为30,子类为5。obj.age得到的结果到底是30还是5,只取决于引用的定义类型。
父类 obj = new 子类();// obj.age == 30
子类 obj2 = new 子类();// obj2.age == 5


■网友
因为子类会从父类那继承到方法或变量,所以父类有的子类都有,你要明白运行是分编译阶段和运行阶段像父类=new 子类()其实这属于迷惑编译器(可以这样理解,父类不可以调用子类方法,除非在向下转型,告诉这是子类),实际上他还是子类,所以调用的是子类的方法这样做有许多好处例如你写的一个传参是动物,但猫什么的都可以传入,因为动物 xx=new 猫()
■网友
子类是父类的增强,父类有的子类也会有,所以向上转型是安全的,即可以使用父类的情况下实际使用的是子类的引用也是合适的。override的实现主要是方法的动态分派(dispatch)。new 子类返回一个子类的引用,不管静态类型是父类还是子类,实际都指向一个子类实例,循着继承链去寻找符合对应方法签名的方法然后调用。
■网友
父类 obj = new 子类();
obj.methods
这个obj不是子类的实例么,当然可以调用子类的方法了。
【Java的多态为何可以由子类实例化父类】 子类里的方法你看是重载父类的方法,还是重写。如果是重载的话那父类是没法调用的,因为相当于父类里没该方法,重写的话是可以调用的


推荐阅读