Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 继承和动态绑定的原理不清楚_Java_Inheritance - Fatal编程技术网

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(

我在理解继承和动态绑定时遇到了一个问题。我目前正在阅读一本面向初学者的java书籍,本例中有一个例子

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
中被覆盖,但这不是必需的。这意味着如果我在子类中写下完全相同的方法,则不会被覆盖,并且它与父类中的方法相同。否。它被覆盖。编译器“不够聪明”,无法看到这些方法是相同的。如果不希望替代,请不要替代。然后,该方法从超类继承而来。但它最终只是同一个方法,对吗?