public class Test {
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("看家");
}
}
Animal a = new Cat(); 中抽象类不是不可以实例化么!为啥还可以通过参数抽象父类引用子类对象?new一个子类对象
Animal a = new Cat();
父类指向了子类对象,向上转型。
创建的对象是子类Cat对象,当然没问题。
抽象类和接口不能实例化,但是可以声明。
所以父类指向子类引用没问题。
因为java中你new的什么就是什么,变量名和变量类型不重要,重要的是new的时候调用的哪一个类。
比如你做了一锅炒饭,相当于new 炒饭()
,你可以直接炒饭 自己做的饭=new 炒饭()
,当你每次提到自己做的饭
时,指的就是你new出来的那个实例。
炒饭可能还有一个抽象类:食物。这显然是一个概念,是不能实例化的,但你仍可以食物 自己做的饭=new 炒饭()
,因为炒饭是一种食物,你做了炒饭,你也可以指着炒饭管它叫食物,但是这时你强调的是食物这个整体概念
子类对象可以啊。a实际是Cat对象,但Animal a = new Animal是不行的