Java基础——多态详解
-
定义:同一种行为,具有不同的表现形式。(例如:动物都有吃的行为,而不同种类的动物,吃的东西不同,猫吃鱼、狗吃骨头、老虎吃人。在该案例中,定义一个Animal抽象类,类中定义抽象方法eat(),则继承该类的子类都需要重写eat()方法,且方法中的实现不同。定义一个Animal对象引用,可以将其指向不同的子类对象,调用eat()方法,实现多态。)
-
三个必要条件:
继承或实现
方法重写
父类引用指向子类对象
-
当使用多态方式调用方法时,首先检查父类中是否有该方法。
如果没有:编译报错
如果有:执行的是子类重写的方法
-
多态的好处
编写一个show()方法可以将父类类型作为形参,子类对象作为实参。则不用单独写showCat()、showDog()等方法。可以简化开发、拓展性好。
-
向上转型和向下转型
向上转型:默认的过程;一个父类引用指向一个子类对象。Animal a = new Cat();
向下转型:强制过程;一个已经向上转型的子类对象,将父类引用转为子类引用,使用强制类型转换的格式,即向下转型。Cat c = (Cat)a;
-
为什么转型
多态调用方法时,如果子类中有而父类中没有该方法,则编译报错(即不能调用子类特定的方法)。因此如果想要调用子类特有的方法,必须要向下转型。
-
instanceof用法
变量名 instanceof 数据类型
变量属于该类型返回true,不属于返回false。
-
多态中使用instanceof:
对于一个已经向上转型的对象Animal a = new Cat();如果在向下转型时将其转为了其他子类的类型Dog d = (Dog)a;此时虽然能够通过编译,但在运行期会报ClassCastException异常。因此在进行强制转换之前,最好先使用instanceof做一个判断。
-
代码示例
public class Test {
public static void main(String[] args) {
show(new Cat());
show(new Dog());
Animal a = new Cat(); // 向上转型
a.eat(); // 调用的是 Cat 的 eat
Cat c = (Cat)a; // 向下转型
c.eat(); // 调用的是 Cat 的 work
}
//父类类型作为形参,子类对象作为实参。则不用单独写showCat()、showDog()等方法。
public static void show(Animal a) {
if (a instanceof Cat) { // 判断a是否是Cat的实例,避免一个Cat的对象被强转为Dog对象,会出现运行时异常。
Cat c = (Cat)a;
c.eat();
} else if (a instanceof Dog) {
Dog d = (Dog)a;
d.eat();
}
}
}
abstract class Animal {
abstract void eat();
}
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
}