Java中抽象类不是不可以实例化么!为啥还可以通过参数抽象父类引用子类对象?new一个子类对象


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是不行的