java中的多态
java中多态一般是以上转形对象实现的,多态要实现一般具有一下条件:
-
继承的存在(继承是多态的基础,没有继承就没有多态);
-
子类重写父类的方法(多态下调用子类重写的方法);
-
父类引用变量指向子类对象(子类到父类的类型转换)。
子类转换成父类时的规则:
将一个父类的引用指向一个子类的对象,称为向上转型(upcasting),自动进行类型转换。此时通过父类引用调用的方法是子类覆盖或继承父类的方法,不是父类的方法。 此时通过父类引用变量无法调用子类特有的方法;
如果父类要调用子类的特有方法就得将一个指向子类对象的父类引用赋给一个子类的引用,称为向下转型,此时必须进行强制类型转换。
编程案例:
public class TestAnimalDemo {
public static void main(String[] args) {
show(new Cat()); // 以 Cat 对象调用 show 方法
show(new Dog()); // 以 Dog 对象调用 show 方法
Animal a = new Cat(); // 向上转型
a.eat(); // 调用的是 Cat 的 eat
Cat c = (Cat) a; // 向下转型
c.work(); // 调用的是 Cat 的 work
}
public static void show(Animal a) {
a.eat();
// 类型判断
if (a instanceof Cat) { // 猫做的事情
Cat c = (Cat) a;
c.work();
} else if (a instanceof Dog) { // 狗做的事情
Dog c = (Dog) a;
c.work();
}
}
}
abstract class Animal {
abstract void eat();
}
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
public void work() {
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
public void work() {
System.out.println("看家");
}
}
输出结果:
吃鱼
抓老鼠
吃骨头
看家
吃鱼
抓老鼠
需要注意,上文代码中的show()
中用到了两个强转,把对象a
强转为Cat
类型,这个就是下转形对象的实现形式,这种强转方法只使用在上转对象在父类子类之间切换,而不能将上转形对象直接强转成别的子类的对象
例如
package case8;
public class TestPolymorphism {
public static void main(String[] args) {
// 以多态方式分别实例化子类对象并调用eat()方法
/********* begin *********/
Animal a = new Dog();
a.eat();
Cat c = (Cat) a; //错误用法
c.eat();
Lion l = (Lion) a; //错误用法
l.eat();
/********* end *********/
}
}
// Animal类中定义eat()方法
abstract class Animal {
/********* begin *********/
abstract void eat();
/********* end *********/
}
// Dog类继承Animal类 复写eat()方法
class Dog extends Animal {
/********* begin *********/
void eat(){
System.out.println("eating bread...");
}
/********* end *********/
}
// Cat类继承Animal类 复写eat()方法
class Cat extends Animal {
/********* begin *********/
void eat(){
System.out.println("eating rat...");
}
/********* end *********/
}
// Lion类继承Animal类 复写eat()方法
class Lion extends Animal {
/********* begin *********/
void eat(){
System.out.println("eating meat...");
}
/********* end *********/
}
尝试将Animal对象强制转换为Cat和Lion对象可能会导致ClassCastException异常。这是因为在实例化Animal a = new Dog()时,a引用的实际对象类型是Dog,而不是Cat或Lion。因此,无法将Animal对象直接转换为Cat或Lion。