众所周知,java的多态有三种实现形式。一种是通过方法重载,一种是实现借口,一种是继承父类。当然这只是简便说法,比如继承里面要有多态,必须有方法重写,且有父类对象指向子类实例。下面就是我做的测试
public class ExtendTest { public static void main(String[] args) { Father father = new Child();//Java polymorphism father.fatherMethod(); father.publicMethod(); // father.childMethod();//error, parent class can not access child method "childMethod". Child.staticMethod();//render static method using class name directly. Father.staticMethod();//render static method using class name directly. } } class Father { //1, before initialize. static { System.out.println("father pre static method."); } //3, constructor method. public Father() { System.out.println("father constructor initialized."); } private void privateMethod() { System.out.println("father private method."); } public void fatherMethod() { privateMethod();//this is the way to render private method in parent class System.out.println("father self method."); } public void publicMethod() { System.out.println("father public method."); } public static void staticMethod() { System.out.println("father static method."); } } class Child extends Father { //2, before initialize. static { System.out.println("child pre static method."); } //4, constructor method. public Child() { System.out.println("child constructor initilized."); } public void childMethod() { System.out.println("child slef mehtod."); } @Override public void publicMethod() { System.out.println("child public method."); } //@Override //error, static method can not be overrided. public static void staticMethod() { System.out.println("child static method."); } }
输出结果如下:
father pre static method. child pre static method. father constructor initialized. child constructor initilized. father private method. father self method. child public method. child static method. father static method.
想必这还是比较好理解的。
下面是一个略微有些妖的关于继承的问题:
public class ExtendTestPro { public static void main(String[] args) { A a1 = new A(); A a2 = new B(); B b = new B(); C c = new C(); D d = new D(); System.out.println(a1.show(b));//A and A System.out.println(a1.show(c));//A and A System.out.println(a1.show(d));//A and D System.out.println(a2.show(b));//B and A System.out.println(a2.show(c));//B and A System.out.println(a2.show(d));//A and D System.out.println(b.show(b));//B and B System.out.println(b.show(c));//B and B System.out.println(b.show(d));//A and D } } class A { public String show(D obj) { return ("A and D"); } public String show(A obj) { return ("A and A"); } } class B extends A { public String show(B obj) { return ("B and B"); } public String show(A obj ){ return ("B and A"); } } class C extends B {} class D extends B {}
第一个输出其实就体现了java的多态了。a1.show(b)输出的是"A and A",因为A类里面没有public String show(B obj){}这样的方法,所以这里把b类强转成了A类,类似这样:A a = (A)b; 所以调用的是public String show(A obj){}方法。
第四个a2.show(b)为什么输出"B and A"?这应该就是最妖的一个了。首先要理解A a2 = new B(); 这句话做了什么。其实它是创建了两个对象,一个A对象a2,一个B对象,而a2是指向B对象的。所以归根结底a2还是个A(父类)对象,不能调用子类新定义的方法。所以当走到a2.show(b)的时候,它其实去调用的是public String show(A obj){}方法,而恰好这个方法被子类B重写了,所以输出"B and A"。
第八个之所以输出"B and B" 而不是 "B and A",是因为它只会去找它最近的父类来强转它。比如这里的c对象,就会用B类来转,而不是A类。
原文:http://my.oschina.net/u/2411391/blog/519334