- 多态:父类类型(比如Mammal)的变量(比如mammal)指向子类创建的对象(whale),使用该变量调用父类中一个被子类重写的方法(比如move方法),则父类中的方法呈现出不同的行为特征,这就是多态。
Java引用变量有两种类型,分别是编译时类型和运行时类型:编译时类型由声明该变量时使用的类型决定;运行时类型由实际赋给该变量的对象。如果编译时类型和运行时类型不一致,就可能出现所谓多态。
- 父类类型变量 = 子类创建的对象
编译时变量为父类类型,所以编译时调用父类中的move方法;
运行时,mammal变量指向子类whale创建的对象,所以运行时调用的是子类whale的move方法。
编译时和运行时调用的方法不一致,便是多态,即多种行为状态。
package src;
public class Mammal {
public void move() {
System.out.println("正在移动");
}
}
package src;
public class Whale extends Mammal {
@Override
public void move() {
System.out.println("鲸鱼靠鳍移动······");
}
}
package src;
public class Testi {
public static void main(String[] args) {
Whale whale =new Whale();
whale.move();
System.out.println("~~~~~~~");
Mammal mammal = whale;
mammal.move();
}
}
- 多态特点:
- 编译时和运行时类型不一致,否则一定不会产生多态
- 编译时调用的方法一定被子类所重写
- 父类类型变量 = 子类创建的对象(又称为上转型对象)
- 上转型对象特点:
- 上转型对象不能调用子类"新增"的属性和方法,上转型对象如果必须调用子类新增的属性和方法,则必须下转型。
//错误代码 Mammal mammal1 = new Bat();//父类类型变量 = 子类创建的对象 mammal1.move(); int x = (int)9.0; Bat b = (Bat)mammal; System.out.println(b.weight); b.eat();
- 非上转型对象不能下转型
Mammal m = new Mammal(); Bat bb = (Bat)m;//因为m变量中保存的不是上转型对象,所以不能下转型
- 如果子类成员变量与父类成员变量名字重复,则上转型对象调用的是父类中的方法
package src; public class Mammal { String weight ="1.2Kg"; public void move() { System.out.println("正在移动"); } public void eat() { } } package src; public class Whale extends Mammal { @Override public void move() { System.out.println("鲸鱼靠鳍移动······"); } } package src; public class Testi { public static void main(String[] args) { Whale whale =new Whale(); whale.move(); System.out.println("~~~~~~~"); Mammal mammal = whale; mammal.move(); System.out.println(mammal.weight); } }
//运行结果 鲸鱼靠鳍移动······ ~~~~~~~ 鲸鱼靠鳍移动······ 1.2Kg