多态
1:什么是多态
所谓多态,就是指一个引用变量在不同的情况下的多种表现状态。也可以理解为,多态是指通过指向父类的引用变量,来调用在不同子类中实现的方法。
注意:方法重写是实现多态的基础
2:多态的运用
一般用于继承体系下,子类重写父类的某个方法,调用时根据具体的子类实现去调用子类的方法
3:向上转型
把子类对象直接赋给父类引用叫向上转型,向上转型不用强制转换。
<父类型> <引用变量名> = new <子类型>();
// 使用多态方法创建对象:
// 能调用父类中的方法,子类重写了父类的方法,但不能调用子类特有的方法
Pet dog2 = new Dog(); //类型转换,向上转型
注意:
1、此时通过父类引用变量调用的方法是子类重写或继承父类的方法
2、此时通过父类引用变量无法调用子类特有的方法
4:向下转型 - 强制类型转换
向上转型只能使用子类重写的一些方法,和从父类中继承的一些方法,,不能使用子类特有的方法。
如果想要调用子类特有的方法
1.直接创建子类对象
2.强制类型转换
// 如果想要调用子类特有的方法
// 1.直接创建子类对象; 2.强制类型转换
Dog dog3 = (Dog)dog2;
// 每晚22:00睡觉
dog3.sleep();
Dog dog3 = (Dog)dog2;//将dog2转换为Dog类型
dog3.sleep();//执行Dog特有的方法
在进行向下转型的时候,非常容易发生类型转换异常,
ClassCastException — 类型转换异常
instanceof用于判断一个引用类型所引用的对象是否是一个类的实例
多态使用演示
需求说明:宠物饿了,主人需要喂食,使用多态实现
1.不同宠物吃的东西不一样
2.不同宠物吃完东西后恢复的健康值不一样
3.健康值达到100时不需要喂食
测试
package poly;
// 测试
public class Demo {
public static void main(String[] args) {
// 创建子类对象
Dog dog1 = new Dog();
Cat cat1 = new Cat();
// 多态仅仅是编写代码的一种习惯
// 多态:父类的引用变量,指向子类的实例
// 多态的编写方式
Master master = new Master();
// 主人带着宠物去医院
master.cure(dog1); //狗生病了,要去宠物医院
// 设置猫和狗的初始健康值
dog1.setHealth(99); //狗投食前健康值:65
cat1.setHealth(65); //猫投食前健康值:65
// 投食一次后的健康值
master.full(dog1); //狗投食后健康值:70
master.full(cat1); //猫投食后健康值:68
// 使用多态方法创建对象:
// 能调用父类中的方法,子类重写了父类的方法,但不能调用子类特有的方法
Pet dog2 = new Dog(); //类型转换,向上转型
// 如果想要调用子类特有的方法
// 1.直接创建子类对象; 2.强制类型转换
Dog dog3 = (Dog)dog2;
// 每晚22:00睡觉
dog3.sleep();
}
}
父类
package poly;
// 父类:公共的方法
public class Pet {
private String name;
private int health;
private int lovely;
public void hospital(){
System.out.println("生病了,去医院");
}
public void eat(){
System.out.println("我喜欢吃零食");
}
// 取值赋值
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
public int getLovely() {
return lovely;
}
public void setLovely(int lovely) {
this.lovely = lovely;
}
@Override
public String toString() {
return "Pet [name=" + name + ", health=" + health + ", lovely="
+ lovely + "]";
}
// 有参无参构造方法
public Pet() {
super();
// TODO Auto-generated constructor stub
}
public Pet(String name, int health, int lovely) {
super();
this.name = name;
this.health = health;
this.lovely = lovely;
}
}
子类Dog
package poly;
// 子类
public class Dog extends Pet {
// 子类重写父类的方法
public void hospital(){
System.out.println("狗生病了,要去宠物医院");
}
public void eat(){
System.out.println("狗狗喜欢吃牛肉");
this.setLovely(5);
}
// 子类特有的方法
public void sleep(){
System.out.println("每晚22:00睡觉");
}
}
子类Cat
package poly;
// 子类
public class Cat extends Pet {
// 子类重写父类的方法
public void hospital(){
System.out.println("猫生病了,要去宠物医院");
}
public void eat(){
System.out.println("猫猫喜欢吃鱼肉");
this.setLovely(3);
}
}
主人类
package poly;
// 主人类
public class Master {
// Pet父类作为参数是多态常用的一种方式,在传递具体参数时,可以传递子类的对象
// 多态就是指一个引用变量在不同的情况下的多种表现形式
// (Pet pet):不仅可以传父类本身还可以传子类
public void cure(Pet pet){
// 如果健康值小于60,带宠物去医院
if (pet.getHealth() < 60) {
pet.hospital(); //真正调用的是子类的具体方法
}
}
public void full(Pet pet){
pet.eat();
// 当健康值是否小于100
if (pet.getHealth() >= 100) {
// 当进入这里表示健康值大于等于100,不需要投食
System.out.println("已经饱了,不需要再吃东西了");
} else {
// 当进入这里表示健康值小于100,需要投食,上限是100,不能超过
System.out.println("投食前健康值:"+pet.getHealth());
// 投食后健康值增加
int num = pet.getHealth() + pet.getLovely();
System.out.println("饱餐一顿 ---> 健康值+"+pet.getLovely());
if (num < 100) {
pet.setHealth(num);
} else {
pet.setHealth(100);
}
}
System.out.println("投食后健康值:"+pet.getHealth());
}
}