多态是继封装、继承之后,面向对象的第三大特性。它表示一个对象具有多重特征,可以在特定的情况下表现出不同的状态。
多态的形式和体现
多态引用
父类类型 变量名 = 子类对象;
多态引用的好处和弊端
弊端:编译时,只能调用父类声明的方法,不能调用子类扩展的方法;
好处:运行时,看“子类”,如果子类重写了方法,一定是执行子类重写的方法体;变量引用的子类对象不同,执行的方法就不同,实现动态绑定。代码编写更灵活、功能更强大,可维护性和扩展性更好了。
多态演示
package com.haogu.polymorphism.grammar;
public class Pet {
private String nickname;
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public void eat(){
System.out.println(nickname + "吃东西");
}
}
package com.haogu.polymorphism.grammar;
public class Cat extends Pet {
//子类重写父类的方法
@Override
public void eat() {
System.out.println("猫咪" + getNickname() + "吃鱼仔");
}
//子类扩展的方法
public void catchMouse() {
System.out.println("抓老鼠");
}
}
package com.haogu.polymorphism.grammar;
public class Dog extends Pet {
//子类重写父类的方法
@Override
public void eat() {
System.out.println("狗狗" + getNickname() + "啃骨头");
}
//子类扩展的方法
public void watchHouse() {
System.out.println("看家");
}
}
package com.haogu.polymorphism.grammar;
public class TestPet {
public static void main(String[] args) {
//多态引用
Pet pet = new Dog();
pet.setNickname("小白");
//多态的表现形式
/*
编译时看父类:只能调用父类声明的方法,不能调用子类扩展的方法;
运行时,看“子类”,如果子类重写了方法,一定是执行子类重写的方法体;
*/
pet.eat();//运行时执行子类Dog重写的方法
// pet.watchHouse();//不能调用Dog子类扩展的方法
pet = new Cat();
pet.setNickname("雪球");
pet.eat();//运行时执行子类Cat重写的方法
}
}
应用多态解决问题
1、声明变量是父类类型,变量赋值子类对象
-
方法的形参是父类类型,调用方法的实参是子类对象
-
实例变量声明父类类型,实际存储的是子类对象
2、数组元素是父类类型,元素对象是子类对象
package com.haogu.polymorphism.grammar;
public class OnePersonManyPets {
private Pet[] pets;//数组元素类型是父类类型,元素存储的是子类对象
public void adopt(Pet[] pets) {
this.pets = pets;
}
public void feed() {
for (int i = 0; i < pets.length; i++) {
pets[i].eat();//pets[i]实际引用的对象类型不同,执行的eat方法也不同
}
}
}
package com.haogu.polymorphism.grammar;
public class TestPets {
public static void main(String[] args) {
Pet[] pets = new Pet[2];
pets[0] = new Dog();//多态引用
pets[0].setNickname("小白");
pets[1] = new Cat();//多态引用
pets[1].setNickname("雪球");
OnePersonManyPets person = new OnePersonManyPets();
person.adopt(pets);
person.feed();
}
}
3、方法返回值类型声明为父类类型,实际返回的是子类对象
package com.haogu.polymorphism.grammar;
public class PetShop {
//返回值类型是父类类型,实际返回的是子类对象
public Pet sale(String type){
switch (type){
case "Dog":
return new Dog();
case "Cat":
return new Cat();
}
return null;
}
}
package com.haogu.polymorphism.grammar;
public class TestPetShop {
public static void main(String[] args) {
PetShop shop = new PetShop();
Pet dog = shop.sale("Dog");
dog.setNickname("小白");
dog.eat();
Pet cat = shop.sale("Cat");
cat.setNickname("雪球");
cat.eat();
}
}