多态在Java中应用非常广泛,好处很多,但是有需要注意的地方。
一、覆盖私有方法
package com.study.base;
public class Polymorphic {
private void f(){
System.out.println("父类f()方法执行");
}
public static void main(String[] args){
Polymorphic po = new Derived();
po.f();
}
}
class Derived extends Polymorphic{
public void f(){
System.out.println("子类的f()方法执行");
}
}
运行上面的main方法,运行的结果如下,可以看到本来我们预期是应该输出的是"子类f()方法执行"。但是实际输出的却是"父类f()方法执行",之所以会出现这种现象,是因为在父类中f()方法是私有的,这样的话,子类虽然继承了父类,但是子类中的f()方法已经是新的方法了,与父类的f()方法没有什么关系。而我们的main方法是写在父类当中,因此输出的便是父类的f()方法。如果父类的f()方法是public的话,子类才会覆盖父类的f()方法,输出才会按照我们期望的进行输出。
二、域
package com.study.base;
class Super{
public int field = 0;
public int getField(){
return field;
}
}
class Sub extends Super{
public int field = 1;
public int getField(){
return field;
}
public int getSuperField(){
return super.field;
}
}
public class FieldAccess {
public static void main(String[] args){
Super sup = new Sub();
System.out.println("sup.field="+sup.field+" sup.getField()="+sup.getField());
Sub s = new Sub();
System.out.println("s.field="+s.field+" s.getField()="+s.getField());
System.out.println("s.getSuperField="+s.getSuperField());
}
}
运行上面的代码,运行结果如下所示:
sup.field=0 sup.getField()=1
s.field=1 s.getField()=1
s.getSuperField=0
之所以出现上面的结果是因为多态针对的是公有的非静态的getField()方法,而不是字段(域),所以sup虽然指向子类的实例,但是由于sup.field直接访问的是域,而域不具有多态性,因此输出的是基类的field的值0。getField()方法是公有的,并且是非静态的,因此它具备多态性,所以sup.getField()方法输出的是子类的field的值,也就是1。至于s.field和s.getField(),由于实例化时便都是子类,因此没有什么可说的,都是1。第三句输出是指从子类访问父类的field的值,当然得到的值便是0。
三、静态方法
package com.study.base;
class StaticSuper{
public static String staticGet(){
return "Base staticGet()";
}
public String dynamicGet(){
return "Base dynamicGet()";
}
}
class StaticSub extends StaticSuper{
public static String staticGet(){
return "Sub staticGet()";
}
public String dynamicGet(){
return "Sub dynamicGet()";
}
}
public class StaticPolymorphic {
public static void main(String[] args){
StaticSuper sup = new StaticSub();
System.out.println(sup.staticGet());
System.out.println(sup.dynamicGet());
}
}
运行上面的代码,结果如下:
Base staticGet()
Sub dynamicGet()
出现上面的结果是因为静态方法是没有多态性的,因此用父类指向子类的实例也无法访问子类的静态方法,只能访问子类的动态方法。
以上便是在使用多态时应该注意的地方。