0

请问为什么在petMap.put那里,Pet类的对象可以用new Cat(),new Dog()构造,这跟构造器有什么不同?涉及到了具体哪块知识?并且为什么在输出时,Cat Dog也能出现在输出结果里?恳请点拨!


import typeinfo.pets.*
import java.util.*
import static net.mindview.util.Print.*

public class PetMap {
    public static void main(String[] args) {
        Map<String, Pet> petMap = new HashMap<String, Pet>();
        petMap.put("My Cat", new Cat("Molly"));
        petMap.put("My Dog", new Dog("Ginger"));
        petMap.put("My Hamster", new Hamster("Bosco"));
        print(petMap);
        Pet dog = petMap.get("My Dog");
        print(dog);
    }
} 

/* Output:
{My Cat=Cat Molly, My Hamster=Hamster Bosco, My Dog=Dog Ginger}
Dog Ginger

2个回答

3

你说的应该是继承吧?定义一个接口,然后用类去实现,就可以实现你说的构造了(父类引用指向子类)。是java三大特种之一的多态里面的内容。
例子:
接口如下:

interface Pet {
    void eat();
}

实现类如下:

class Cat implements Pet{
    @Override[override] 
    public void eat() {
        System.out.print("猫吃鱼");
    }
}
class Dog implements Pet{
    @Override[override] 
    public void eat() {
        System.out.print("狗吃骨头")
    }
}

测试类代码如下:

class Test {
    public static void main(String[] args) {
        Pet a = new Cat();
        Pet b = new Dog();
        a.eat();
        b.eat();
    }
}
1

很简单,继承。
‘Pet类的对象可以用new Cat(),new Dog()构造’,题主这句话我看着总觉得有点别扭;从贴的代码来看 ,Cat和Dog这两个类肯定是继承或者了Pet类的,而这句话用白话来说就是猫类和狗类都是宠物这个基类的子类,而所有能用基类对象的地方都应该能用子类对象,这是java的语言特性,也好理解,因为所有的猫和狗都是宠物,但不是所有的宠物都是猫和狗;
再说‘并且为什么在输出时,Cat Dog也能出现在输出结果里’,想必题主是在Cat和Dog类的构造器里加了输出的,这里要说的是父类和子类的构造器调用顺序,当Pet dog = new Dog("xxx")这句话执行的时候,会先去调用父类的构造器(如果有的话),然后会调用子类的构造器,这个时候,Dog的类构造器中加的print就会执行,并且是不同的子类都会有不同的输出。
相对来说很基础的一个问题,说到底最根本的就是父类子类的替换,具体你可以看看里氏代换原则。

撰写答案