什么是多态?
首先方法重写是实现多态的基础:[方法重写传送门(https://blog.csdn.net/weixin_43400205/article/details/95091543)
多态:同一个引用类型,使用不同的实例而执行不同的操作。就像同样是打印机,彩色打印机就可以打印彩色图片。即同一种事物,由于条件不同,产生的结果也不同
多态的使用
举个栗子:如果一只猫和一只狗,它们的健康值在50以下时就要去医院,猫是吃药、疗养,狗是打针、吃药
Dog类
public class Dog extends Pet{
public void toHospital(){
this.setHealth(50);
System.out.lrintln("打针、吃药")
}
}
Cat类
public class Cat extends Pet{
public void toHospital() {
this.setHealth(20);
System.out.println("吃药、疗养");
}
}
Master类
public class Master{
public void sure(Pet pet){
if(pet.getHealth < 50){
pet.toHealth();
}
}
}
Test类
Pet pet = new Dog();//父类引用指向子类对象
Master master = new Master();
master.cure(pet);
我们在子类中重写了Pet的toHospital()方法,那么Pet中toHospital()如何实现?
- toHospital()不需要有具体实现
- 抽象方法
- Pet声明为抽象类
- 实例化Pet毫无意义
public abstract class Pet{
}
抽象类与抽象方法
什么是抽象类?
使用abstract修饰的类称为抽象类
什么是抽象方法?
例如上面的toHospital();方法,在父类中没有任何作用,是指被拿到子类中重写,就可以写成抽象方法
public abstract void toHospital();
PS:
- 抽象方法没有方法体(没有{}这个东西)
- 抽象方法必须在抽象类中,但抽象类中可以有普通方法
- 抽象方法必须在子类中被实现(重写),除非子类是抽象类
- 抽象类没法new对象,只能通过子类实现,如下
Pet pet = new Dog();
这种方式又称为向上转型,父类引用指向子类对象,自动进行类型转换
但是:
1. 此时通过父类引用变量调用的方法,是子类重写或者继承父类的方法,不是父类的方法
2. 此时通过父类引用变量无法调用子类特有的放法(虽然我new了一个Dog类的,但是此时已经自动提升为Pet类的,无法再使用Dog中特有的方法)
向下转型:如果我需要调用子类对象的话,怎么办?再手动强转回来
Dog dog = (Dog)pet;//将pet再转回来,执行狗特有的方法
PS:需要强转成子类的父类引用必须指向子类对象(啥玩意?),也就是说强转的父类对象必须是new子类得到的(还不明白?),说白了就是如果你是儿子,让你当会儿爹,再让你当回儿子,没问题!但是,如果你是爹,现在让你当儿子,不行!
可以通过instanceof来判断向下转型过程中,是否转换为真实子类类型
if(pet instanceof Dog){
Dog dog = (Dog)pet;
}