当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法,但是它仍然要根据继承链中方法调用的优先级来确认方法,该优先级为:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。这里的this原文作者理解为引用变量的类型,自己理解为实际的对象类型,这并不影响判断的正确性,如果理解为引用变量的类型,那么在最后还是要向下转型成为真正的对象的类型。
上面的结论在C#和Java中是一样的,并且优先级顺序也是一样的。不相同的是C# 和Java的语法不一样,C# 中需要使用virtual和override来声明虚方法和重写的方法,不然编译器不会认为是多态的体现,而在Java中则不需要使用。
上面红字部分的意思很重要,这是向上转型的多态中最重要的体现:被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的。如果这个方法在引用对象的类型中重写了,那么就是这调用这个方法,如果没有,那么则调用父类中的方法。 |
|