这是我在研究遗产时在网上找到的一个例子。
class Animal {
public void move() {
System.out.println("Animals can move");
}
}
class Dog extends Animal {
public void move() {
System.out.println("Dogs can walk and run");
}
}
public class TestDog {
public static void main(String args[]) {
Animal a = new Animal();
Animal b = new Dog();
a.move(); // runs the method in Animal class
b.move(); // runs the method in Dog class
}
}
我主要的困惑是主方法中的一行:Animal b = new Dog();
我明白 :
Animal是类名
b是对象引用
新的内存分配
狗是建设者电话
但'b'在哪里提到的确切?
什么是Animal b = new Dog();在做什么?
如果Dog扩展Animal,为什么它Animal b = new Dog而不是Dog b = new Dog();?
如果我用Dog b = new Dog();替换该行,那么与Animal b = new Dog();的区别是什么
动物b =新狗()意味着,动物参考和狗对象?
b引用了Dog的实例,但是b在羊皮服装中充当Animal ...狼的实例 - 欢迎使用多态
你为什么用Listlist = new ArrayList<>()?将代码与特定实现分离。与动物和狗相同。当您的狗成为猫时,您的代码中只需要进行一次更改,因为使用Animal仍然是正确的。
@MaccenWright这在内部意味着什么?这个怎么运作?它引用Animal类并为dog类创建一个对象?我无法理解内部发生的事情。
这是多态性和向上转换。 Animal b = new Dog();这一行意味着你可以使用Animal类接口,你可以在编译时使用Animals方法。但是在运行时Dog类的方法运行。
你应该从现实生活的角度来看待它。你有一只动物狗。当你调用你的动物的声音行为时,在这种情况下它是一只狗,它将返回"Aw aw aw"。如果你有动物猫,它会说"喵"。
Animal b;
声明一个名为b的变量,用于存储Animal对象。 Dog是Animal的一种吗?是。所以狗可以放入b。完全没问题。
If Dog extends Animal, why is it Animal b = new Dog and not Dog b = new Dog();
没有明显的理由,如果这是所有的代码。编写代码的人认为,让我们这样做,所以他做到了。
给定更多上下文,编写代码的人可能希望稍后存储其他动物,例如Cat。如果他宣称它像Dog b,他以后就不能在其中存储Cat。
另一个原因可能是只展示多态性。它证明了"是的,你确实可以将狗分配给动物变量。这是因为Dog扩展了Animal!"
那么Animal b和Dog b之间有什么区别?
使用当前代码,没有区别。但是如果你在Dog中声明了更多的成员,你会看到差异。我们在Dog中编写了一个名为bark的方法。使用Animal b,您无法访问bark,但使用Dog b,您可以。这是因为对于前者,编译器认为b是Animal,而不是Dog。 (实际上,这很难)
你需要更多地注重良好实践,比如编程到接口和松散耦合,而不是说"没有明显的理由,如果这就是所有的代码"。 否则很好解释。
使用Dog b = new Dog()没有任何问题。
这只是创建一个Dog对象。
现在,
Animal a = new Animal();
动物b =新狗();
对象b即使具有Animal引用,Dog对象也会在运行时创建。所以基本上你可以使用超类引用来实例化子类对象。因此,这仅用于显示方法覆盖,因为您可以使用超类引用调用子类方法"move"。
"="的左手表示变量"b"的声明类,右手是精确的类。
Class Dog扩展了Animal类,一个变量可以声明为父类,并由子类实现。
运行下面的代码,你可以得到"真实"。
System.out.println(b instanceof Animal); //真正
System.out.println(b instanceof Dog); //真正