Java 多态缺陷 (摘抄 java编程思想)
output:
1.缺陷 : “覆盖”私有方法
public class A {
private void print() {System.out.println("print A");}
public static void main(String[] args) {
A a = new B();
a.print();
}
}
class B extends A {
public void print() { System.out.println("print B"); }
}
output:
print A
private方法被自动认为是final方法,而且对子类是屏蔽的。因此,在这种情况下,子类B中的print方法是一个全新的方法;既然基类中的print()方法在子类中不可见,因此甚至不能被重载。
结论就是:只有非private方法才可以被覆盖;
可是如上面代码所示,发生private方法覆盖现象时,虽然编译器不会报错,但也不会按照我们的期望执行子类方法。
确切的说,在子类中,对于基类的private方法,最好采用不同名字
2.缺陷:域与静态方法
一旦你了解多态机制,可能就会认为所有事物都可以多态的发生。然而,只有普通的方法调用可以时多态的。如果你直接访问某个域,这个访问就将在编译期进行解析,就像下面的示例所演示的
public class F {
public static void main(String[] args) {
A a = new B();
System.out.println("a.i="+a.i+" , "+"a.geti()="+a.geti());
System.out.println("======================");
B b=new B();
System.out.println("b.i="+b.i+" , "+"b.geti()="+b.geti()+" , "+"b.getSuperi()="+b.getSuperi());
}
}
class A {
public int i=0;
public int geti(){return i;};
}
class B extends A{
public int i=1;
public int geti(){return i;};
public int getSuperi(){return super.i;};
}
output:
a.i=0 , a.geti()=1
======================
b.i=1 , b.geti()=1 , b.getSuperi()=0
当B对象转型成A类引用时,任何域访问操作都将由编译器解析,因此不是多态的。
在本例子中,为A.i B.i 分配了不同的存储空间。B类中实际上包含了两个称为i的域,this.i super.i
在引用子类B的i域时,所产生的默认域为当前子类的。为了得到super.i ,必须显示的指明super.i.
一般来说,域都会设置成private,也不会对基类和子类使用相同名字的域。
静态方法 同时也不具有多态性,可以自己验证