Java 继承和动态绑定的原理不清楚
我在理解继承和动态绑定时遇到了一个问题。我目前正在阅读一本面向初学者的java书籍,本例中有一个例子Java 继承和动态绑定的原理不清楚,java,inheritance,Java,Inheritance,我在理解继承和动态绑定时遇到了一个问题。我目前正在阅读一本面向初学者的java书籍,本例中有一个例子 class Parent { public String getFoo() { return "parentFoo"; } } class Child extends Parent { public String getFoo() { return "childFoo"; } public String getBar(
class Parent {
public String getFoo() {
return "parentFoo";
}
}
class Child extends Parent {
public String getFoo() {
return "childFoo";
}
public String getBar() {
return "childBar";
}
}
class GrandChild extends Child {
public String getFoo() {
return "grandChildFoo";
}
}
Parent p0 = new Child();
p0.getFoo();
p0.getBar();
Child c0 = new GrandChild();
c0.getFoo();
c0.getBar();
GrandChild gc0 = new GrandChild();
gc0.getFoo();
gc0.getBar();
我不明白什么是Parent p0=new Child()代码>意味着。我已经在互联网上和我的书中搜索过,但我没有找到在这里创建新对象的解决方案。
此外,我不明白为什么p0.getBar()代码>给出了一个错误,p0.getFoo()代码>不是。
我非常感谢每一个帮助
干杯伙伴们“我不明白父项p0=new Child();
是什么意思。”-这意味着您创建了一个父项
类型的引用,并用子项
对其进行初始化。这是因为Child
自动从Parent
继承所有属性和方法,因此Child
可以像使用Parent
一样使用。这有时被称为“是-是”关系(一个子关系“是-是”父关系),但我个人不使用这个术语1。以下给出了更合适的定义:
Liskov的行为子类型概念定义了对象的可替代性概念;也就是说,如果S
是T
的子类型,则程序中T
类型的对象可以替换为S
类型的对象,而不改变该程序的任何期望属性(例如正确性)
(注意:这不是语言强制的,因为我们讨论的是语义,编译器没有语义的概念,但它表明,从语法上讲,子类型或子类也总是它的超类型或超类。)
“此外,我不明白为什么p0.getBar();
给出了一个错误,而p0.getFoo();
没有。”——p0
是一个父级
参考。因此,我们只能访问Parent
中定义的属性和方法。尽管p0
的运行时类型实际上是一个子类
,但我们无法访问仅在子类
中定义的方法。为此,让我们创建一个小示例。想象一个类Animal
,有一个方法sound()
。现在让我们想象一下扩展了动物的两个类:狗和鸟。Dog
-类有一个方法isBestOfBois()
,而Bird
-类有一个方法fly()
。我们现在可以这样写:
Animal animal;
if (user selects dog as his animal) {
animal = new Dog();
} else {
animal = new Bird();
}
// animal.isBestOfBois(); should not be accessible, since animal could be a Bird
// animal.fly(); should not be accessible since animal could be a Dog
animal.sound(); // Both Dog and Bird are guaranteed to have a method sound, so this is fine.
1我之所以不使用“is-a”来描述内在关系,是因为它会导致混淆。正方形是长方形吗?或者矩形是正方形?数学家会明确地说,正方形是矩形的一种特殊形式,因此所有的正方形都应该是矩形,因此就继承而言,正方形
应该继承自矩形
。但是,与矩形不同,正方形仅由一个值(其边长)定义,而矩形由两个值(宽度和高度)定义。如果一个正方形是一个矩形,我们改变了一个矩形的宽度,那么高度也会改变,这是否合理呢?因为这会发生在square案中,我认为这是不可接受的行为。因此,就继承关系而言,Square
和Rectangle
不应该处于继承关系中,即使它们之间存在“是-是”关系。为了让事情更直观,用动物代替父母,用哺乳动物代替孩子,用狗代替孙子。狗是哺乳动物的一种,哺乳动物是动物的一种。由于(子“是”父)p0只能使用类Parent and Child中定义的方法。两个类中的方法都会被覆盖,就像p0.getFoo();,正确的?其中使用子类中定义的方法。因此,如果要使用该方法,则该方法必须在两个类中。否则就不可能访问ist,对吗?“因为(一个子”是一个“父”)p0只能使用在类Parent和Child中定义的方法。并且两个类中的方法都会被覆盖,就像p0.getFoo();,对吗?”-是。--“因此,如果要使用该方法,该方法必须在两个类中。否则无法访问ist,对吗?”-否,该方法必须在父类中。它可以在Child
中被覆盖,但这不是必需的。这意味着如果我在子类中写下完全相同的方法,则不会被覆盖,并且它与父类中的方法相同。否。它被覆盖。编译器“不够聪明”,无法看到这些方法是相同的。如果不希望替代,请不要替代。然后,该方法从超类继承而来。但它最终只是同一个方法,对吗?