多态的概念
多态:就是指一个引用(类型)在不同的情况下的多种状态。也可以理解为,多态是通过指向父类的指针来调用在不同子类中实现的方法。
原理:基于向上转型和动态绑定。
(向上转型:子类的对象可以赋值给父类的对象,也就是子类对象可以向上转型为父类类型(里氏代换原则))
(动态绑定:即程序在运行期间由JVM根据对象的类型自动地判断调用哪个方法)
前提:继承关系下,每个子类都定义有一个同名的成员方法。
继承:在多态中必须存在有继承关系的子类和父类。
重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
向上转型:在多态中需要将子类的引用赋给父类的对象,只有这样该引用才能够具备技能调用父类方法和子类的方法。
首先利用向上转型机制,把子类的对象转化为父类的对象,然后转型后的对象通过动态绑定机制自动调用转型签所属子类同名的方法。
例如:在实现动物叫的方法中,由于每种动物叫声不同,因此可以在方法中接收一个动物类型的参数,当传入具体的某种动物时发送具体的叫声。
在java中为了实现多态,允许使用父类类型的变量引用一个子类类型对象,根据子类对象特征的不同,得到不同的运行结果。
public class Animal {
void call(){
System.out.println("动物叫");
}
}
public class Cow extends Animal{
@Override
public void call(){
System.out.println("牛叫...");
}
}
public class Sleep extends Animal {
public void call(){
System.out.println("羊叫...");
}
public void run(){
System.out.println("羊跑...");
}
}
public class example {
public static void main(String[] args) {
Animal a1 = new Cow(); //向上转型
Animal a2 = new Sleep();
a1.call();
a2.call();
}
}
牛叫...
羊叫...
转型过程中需要注意:
向上转型时,子类单独定义的方法会丢失。比如Sleep类中定义的run方法,当Animal引用指向Sleep类实例时,是访问不到run方法的,a2.run()会报错。
子类的引用不能指向父类的对象。Cow a = (Cow)new Animal()这样是不行的。
另外:
向下转型:
向下转型的前提是父类对象指向的是子类对象(也就是说,在向下转型之前,它的先向上转型)
向下转型只能转型为本类对象。
public void call(Animal a){ if(a instanceof Sleep){ Sleep d = (Sleep)a; d.call(); d.run(); } if(a instanceof Cow){ Cow c = (Cow)a; c.call(); System.out.println("我也想跑,但是不会"); } a.call();//其他动物只会吃 }