Java多态性性主要体现在:
1、方法的多态性
(1)方法的重载: 同一个方法名称,根据传入参数类型及个数个数调用不同的方法体
(2)方法的覆写: 同一个方法名称,根据子类的不同,实现不同的功能
2、对象的多态性:发生在继承关系类中,子类和父类转换
(1)向上转型(自动完成): 父类 父类对象 = 子类实例 ;
(2)向下转型(强制完成): 子类 子类对象 = (子类) 父类实例 ;
疑问? 向上和向下转型有什么意义呢?
向上转型: 由于所有的子类对象实例都可以自动实现向上转型,所有有利于参数的统一。参数统一后可以调用子类所覆写的方法体,即同一个方法针对不同的子类有不同的实现,如下:
class A {
public void print() {
System.out.println("A、public void print ()");
}
}
class B extends A {
public void print() {
System.out.println("B、public void print ()") ;
}
}
class C extends A {
public void print() {
System.out.println("C、public void print ()") ;
}
}
public class Tes tDemo {
public static void main (String args [] ) {
//只要是A类的子类都可以使用向,用A来接收
A a1=new B();// 向上转型
A a2=new C();//向上转型
a1.print();
a2.print() ;
}
}
向下转型: 父类要调用子类定义的特殊方法。因为所有的向上转型之后,父类只能看到自己定义的方法,而看不到子类定义的特殊方法,所以就需要向上转型才能实现。如下:
class A {
public void print() {
System.out.println("A、public void print ()");
}
}
class B extends A {
public void print() {
System.out.println("B、public void print ()") ;
}
//子类中新增方法
public void init() {
System.out.println("新扩充的init()方法") ;
}
}
class C extends A {
public void print() {
System.out.println("C、public void print ()") ;
}
}
public class Tes tDemo {
public static void main (String args [] ) {
//只要是A类的子类都可以使用向,用A来接收
A a1=new B();// 向上转型
A a2=new C();//向上转型
B b = (B) a ; //向下转型
a1.print();
a2.print() ;
b.init() ;
}
}
疑问? 为什么不直接new B.init()就OK了?还要花里胡哨的先向上转型再向下转型实现子类特殊方法的调用呢?
原因: (1)向上转型是为了参数统一
(2)向下转型是当父类功能不足时,利用向子类的向下转型来获得父类欠缺的方法(方便新方法扩充)
ps 其实在程序中要尽量避免使用向下转型,因为强制转换关系存在安全隐患(ClassCastException:类转换异常,两个没有关系的类发生强制转换(向下转型)。)
为什么呢? 因为向上转型子类知道自己的父类,而向下转型,父类并不知道强转的到底是不是我的子类?
为了保证转型正确性,java中提供了关键字:instanceof (即有一个instanceof类 返回值是boolean)
条件: 如果某个对象是某个类的实例,返回true,否者返回false
总结:1、如果要发生向下转型,一定要可以先发生向上转型(instanceof判断)建立联系才能发生向下转型。
2、子类不要过多的扩充与父类无关的方法。