Java多态
多态(Polymorphism)按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。Java实现运行时多态性的基础是动态方法调度,它是一种在运行时而不是在编译期调用重载方法的机制。Java多态通过重写Overriding和重载Overloading两种方式来实现。它是面向对象程序设计(OOD)的一个重要特征。如果一个语言只支持类而不支持多态,只能说明它是基于对象的,而不是面向对象的。
Overriding和Overloading的多态性有不同表现。
Overriding: 子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法。 A a= new B(), 是优先调用B的方法。
Overloading则通过参数类型来动态调用不同的方法,方法调用的优先问题 ,优先级由高到低依次为:
this.show(O) > super.show(O) > this.show((super)O) > super.show((super)O)
先是一个简单的例子:
1 class SuperShow { 2 public String str = "SuperStr"; 3 public void show() 4 { 5 System.out.println("Super.show:" + str); 6 } 7 } 8 public class ExtendShow extends SuperShow { 9 public String str = "ExtendStr"; 10 public void show() 11 { 12 System.out.println("Extend.show" + str); 13 } 14 public static void main(String[] args) 15 { 16 ExtendShow ext = new ExtendShow(); 17 SuperShow sup = ext; 18 System.out.println(sup.str); 19 System.out.println(ext.str); 20 sup.show(); 21 ext.show(); 22 } 23 }
输出结果:
SuperStr
ExtendStr
Extend.showExtendStr
Extend.showExtendStr
然后是http://developer.51cto.com/art/200906/130414.htm
1 class A ...{ 2 public String show(D obj)...{ 3 return ("A and D"); 4 } 5 public String show(A obj)...{ 6 return ("A and A"); 7 } 8 } 9 class B extends A...{ 10 public String show(B obj)...{ 11 return ("B and B"); 12 } 13 public String show(A obj)...{ 14 return ("B and A"); 15 } 16 } 17 class C extends B...{} 18 class D extends B...{}
1 A a1 = new A(); 2 A a2 = new B(); 3 B b = new B(); 4 C c = new C(); 5 D d = new D(); 6 System.out.println(a1.show(b)); ① 7 System.out.println(a1.show(c)); ② 8 System.out.println(a1.show(d)); ③ 9 System.out.println(a2.show(b)); ④ 10 System.out.println(a2.show(c)); ⑤ 11 System.out.println(a2.show(d)); ⑥ 12 System.out.println(b.show(b)); ⑦ 13 System.out.println(b.show(c)); ⑧ 14 System.out.println(b.show(d)); ⑨
输出结果是:
① A and A
② A and A
③ A and D
④ B and A
⑤ B and A
⑥ A and D
⑦ B and B
⑧ B and B
⑨ A and D
这里主要涉及到
1. 重写Overriding, 在子类中定义某方法与其父类有相同的名称和参数
2. 重载Overloading, 在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型
Overriding和Overloading的多态性有不同表现。
Overriding: 子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。
当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法。 A a= new B(), 是优先调用B的方法。
方法调用的优先问题 ,优先级由高到低依次为:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。
比如④,a2.show(b),a2是一个引用变量,类型为A,则this为a2,b是B的一个实例,于是它到类A里面找show(B obj)方法,没有找到,于是到A的super(超类)找,而A没有超类,因此转到第三优先级this.show((super)O),this仍然是a2,这里O为B,(super)O即(super)B即A,因此它到类A里面找show(A obj)的方法,类A有这个方法,但是由于a2引用的是类B的一个对象,B覆盖了A的show(A obj)方法,因此最终锁定到类B的show(A obj),输出为"B and A”。
再比如⑧,b.show(c),b是一个引用变量,类型为B,则this为b,c是C的一个实例,于是它到类B找show(C obj)方法,没有找到,转而到B的超类A里面找,A里面也没有,因此也转到第三优先级this.show((super)O),this为b,O为C,(super)O即(super)C即B,因此它到B里面找show(B obj)方法,找到了,由于b引用的是类B的一个对象,因此直接锁定到类B的show(B obj),输出为"B and B”。