声明Java对象但调用子类的构造函数

声明Java对象但调用子类的构造函数,java,class,object,Java,Class,Object,假设有两个Java类,Dog和Poodle。Poodle类扩展了Dog类 创建这些类的实例时,以下是常见语法: Dog myDog = new Dog(); Poodle myPoodle = new Poodle(); 我不明白当您创建父类类型的对象,然后调用子类构造函数时会发生什么,如下所示: Dog myDog = new Poodle(); 如果myDog是一个Dog类,为什么我们要调用它的一个子类的构造函数,这到底意味着什么?为什么不创建一个子类(Poodle)类型的对象呢 换句话

假设有两个Java类,Dog和Poodle。Poodle类扩展了Dog类

创建这些类的实例时,以下是常见语法:

Dog myDog = new Dog();
Poodle myPoodle = new Poodle();
我不明白当您创建父类类型的对象,然后调用子类构造函数时会发生什么,如下所示:

Dog myDog = new Poodle();
如果myDog是一个Dog类,为什么我们要调用它的一个子类的构造函数,这到底意味着什么?为什么不创建一个子类(Poodle)类型的对象呢

换句话说,我不知道这句话是什么意思:“我要创建一个Dog类型的对象,但我要调用它的一个子类的构造函数,即使这个对象不是子类类型的”

我无法从逻辑上理解这意味着什么。请帮我了解这里发生了什么

编辑-链接的重复问题似乎确实在问相同的问题。令人沮丧的是,该页面上投票最多的两个答案没有提供一个明确的示例,说明提问者特别询问的代码段的有意义使用:

Parent parent = new Child();
我理解并遵循了链接重复问题上两个投票最多的答案提供的所有代码段。我甚至知道多态性发生在哪里。但两个答案都没有使用问题中特别提到的代码行。如果有人能给我举个例子,告诉我在哪里,我会非常非常感激

Parent parent = new Child();

在更广泛的代码段中有用且有意义地使用。请我真的非常感谢。

这个概念被称为动态方法调度,通过使用这种运行时多态性(重写)在java中实现

让我们扩展您编写的示例,如下所示

class Dog{

public void bark(){
// parent class implementation
System.out.println("I bark");
}

}
这里我们定义了一个
Dog
类,它有一个名为
bark
的方法,并提供了它的实现

假设
Dog
有两个子类,分别为
Poodle
Chihuahua
,如下所示

class Poodle extends Dog{

@Override
public void bark(){
//Poodle implementation
System.out.println("I bark like Poodle");
}
}

class Chihuahua extends Dog{

@Override
public void bark(){
//Chihuahua implementation
System.out.println("I bark like Chihuahua");
}
}
Dog dog1 = new Poodle();
dog1.bark(); //prints **I bark like Poodle**
Poodle
Chihuahua
类实现了
bark
方法

您创建了一个子对象,并为其指定了一个父对象引用,然后调用树皮方法,如下所示

class Poodle extends Dog{

@Override
public void bark(){
//Poodle implementation
System.out.println("I bark like Poodle");
}
}

class Chihuahua extends Dog{

@Override
public void bark(){
//Chihuahua implementation
System.out.println("I bark like Chihuahua");
}
}
Dog dog1 = new Poodle();
dog1.bark(); //prints **I bark like Poodle**
在运行时,JVM知道您有一个
Poodle
对象,并检查
Poodle
是否覆盖了bark方法,然后调用它

当您执行以下操作时,可以在集合中观察到这种模式

List<String> list = new ArrayList<>();
list.add("test string"); //this gets added according to ArrayList implementation.
List List=new ArrayList();
添加(“测试字符串”)//这是根据ArrayList实现添加的。

可能重复您在30分钟前提出的类似问题。我建议您实际阅读作为重复链接的其他问题,或者——如果您在理解上有困难的话——阅读一篇关于继承的教程。回答您的问题:您在调用类的构造函数时创建了一个对象,因此
new Poodle()
将创建一个
Poodle
实例。如果
Poodle extensed Dog
类型为
Dog
的变量可以引用
Poodle
对象,但该变量本身不是对象,而是引用。StackOverflow不允许我删除或标记为重复,我的另一个问题。@raviraja我已经看完了链接重复页面上的每个答案,还没能更进一步地掌握问题的答案。我编辑了我的问题,希望有人能来帮助我理解。谢谢。@khelwood我翻阅了复本,找不到答案。我已经在我的原始Q中添加了一个编辑。谢谢拉维贾拉,我想我现在明白了这个概念,但我仍然无法想象在现实世界中你会写DogDog1=new Poodle();我在末尾添加了一个关于
List
的示例,该示例在现实世界中大量使用。在您的示例中,为什么不将List声明为ArrayList类型?将公开接口限制为仅列出方法有什么好处?