为什么需要多态?
由于一个对象在不同的时刻表现出不同的状态,不使用多态会使程序丧失可扩展性和后期可维护性。比如,一个打印机要执行打印操作,黑白打印机和彩色打印机都是执行打印操作,但是结果却是一个得到彩色图片,一个得到黑白图片。这就是一个对象在不同的条件下产生了不同的状态。
public class Monster {
//定义一个主人类,用于和宠物互动
//比如宠物生病了,主人要送它去医院
public void toHospital(Dog dog){//带狗去医院
if(dog.health<50){//健康值小于50,则需要治疗
dog.health = 60;
System.out.println("打针,吃药");
}
}
public void toHospital(Penguin pe){//带狗去医院
if(pe.health<50){
pe.health = 60;
System.out.println("打针,吃药");
}
}
}
此时可以发现,有两个宠物就要定义两个几乎一模一样的代码,那么如果有一百个宠物,就要写一百次,这显然不是我们希望看到的情况,因此,为了结局这种问题,引入了多态。
优化后:Pet类是狗和企鹅等动物的父类。
public void toHospital(Pet pet){//带狗去医院
if(pet.health<50){//健康值小于50,则需要治疗
pet.health = 60;
System.out.println("打针,吃药");
}
}
这样只要调用函数的时候参数为pet的子类即可,不需要重复写代码。
多态存在的三个必要条件:
继承
重写
父类引用子类对象 Fu f = new Zi()
方法重写,子类重写父类的方法,其中方法名相同,参数列表也相同。
以下代码包含了instanceof的用法,向下转型的注意事项。
public class Pet{
public void eat(){}
}
public class Dog extends Pet{
public void play(){
System.out.println("接飞盘")
}
public void eat(){
System.out.println("狗吃骨头!");
}
}
public class Penguin extends Pet{
public void eat(){
System.out.println("企鹅吃鱼");
}
}
public class Test{
public static void main(String[] args){
Pet p1 = new Dog();//向上转型
Pet p2 = new Penguin();
p1.eat();//父类引用子类对象,当p1调用方法时,这个方法必须是父类中含有的,然后才会去找子
//类重写之后的方法
p2.eat();
//如果调用父类中没有方法,
p1.play();//此语句会报错,因为p1只在父类里找,找不到这个play方法
//若要调用这个方法,就要将p1向下转型
((Dog)p1).play();//类型转换
Penguin p3 = (Penguin)p1;//这一句编译时不会报错,但运行时会出现类型转换异常
//instanceof的用法
System.out.println(p1 instanceof Dog);//true
System.out.println(p1 instanceof Penguin);//false
}
}