多态
1.什么是多态
父类Mammal中:
public class Mammal {
public void move() {
System.out.println("用脚移动");
}
public void eat() {
System.out.println("用手吃饭");
}
}
子类Whale中:
public class Whale extends Mammal{
public void move() {
System.out.println("用鱼鳍移动");
}
public static void main(String[] args) {
Whale whale = new Whale();
whale.move();//单态
Mammal mammal = new Whale();
mammal.move();//多态
mammal.eat();//单态
}
}
上述代码的Whale中
①将鼠标放在对象.方法的方法上->点击键盘上左下角的‘Ctrl’键->回车
②whale.move(),数据类型和创建的对象都是子类的,只有一种状态
③mammal.move(),数据类型是父类的类型,但是创建的对象却是子类的对象(相当于直接执行代码new Whale().move(),即表面上调用的是父类的方法是一种状态,但是实际上执行的却是子类的方法是另一种状态,共有两种状态,即为多态
④mammal.eat()仍然是一个单态,因为子类没有重写父类的方法所以表面上调用的是父类的方法,实际上执行的还是父类的方法,只有一种状态,即为单态
2.为什么要使用多态
①Mammal mammal为编译时类型,即用javac到生成Class文件,类型都是父类的,调用的也是父类被重写的方法
②new Whale()是运行时类型,即在程序执行的时候,mammal.move()中的对象会被替换为子类Whale中的对象,调用的方法也就变为子类的方法
③当编译时类型和运行时类型不一致的时候就可能会出现多态
3.上转型对象
①把子类实例化的对象赋值给父类声明变量,则该对象称为上转型对象,这个过程称为对象上转型,(类比于数据类型转换中的自动类型转换)
②不能调用子类新增的属性和方法
4.例外
①用上转型对象去调用父类中的age属性
子类:
public class Whale extends Mammal{
int age;
public static void main(String[] args) {
Whale whale = new Whale();
System.out.println(whale.age);
Mammal mammal = new Whale();
System.out.println(mammal.age);
}
}
②如果父类为
public class Mammal {
int age;
}
则实现多态,执行图如下
③
②如果父类为
public class Mammal {
String age;
}
则实现多态,执行图如下
不体现多态,为一个特例
5.对象下转型
(1)含义
将上转型对象再强制转换为创建该对象的子类类型的对象,即将上转型对象还原为子类对象(类比于数据类型转换中的强制类型转换)
(2)为什么下转型
因为上转型对象不能操作子类新增的属性和方法,还原后的对象又具备了子类所有属性和功能,即可以操作子类中继承或新增的成员变量,可以调用子类中继承或新增的方法。
(3)注意
不可以将父类创建的对象通过强制类型转换赋值给子类声明的变量。
①
子类:
public class Whale extends Mammal{
String name;
public static void main(String[] args) {
Mammal mammal = new Whale();
Whale whale = (Whale)mammal;
System.out.println(whale.name);
mammal = new Mammal();
whale = (Whale)mammal;
System.out.println(whale.name);
}
}
②运行后
③因为哺乳动物的种类有很多(即父类中的子类有很多),如果强行把哺乳动物下转型为鲸鱼(即把父类下转型为子类),则鲸鱼不满足哺乳动物的所有特征(即哺乳动物不是鲸鱼),也就是子类特征不包含父类所有特征,故不能将父类的实例化对象下转型为子类