【问题标题】:Inheritance and polymorphism in JavaJava中的继承和多态
【发布时间】:2016-01-24 12:08:35
【问题描述】:

我有 2 个课程:TriangleRightAngledTrRightAngledTr 继承自 Triangle。代码如下:

Triangle 类:

class Triangle {
    public void draw() { 
        System.out.println(“Base::draw\n“);
    }

    public void computeCentroid(Triangle t) {
        System.out.println Base::centroid\n“);
    }
}

RightAngledTr 类:

class RightAngledTr extends Triangle {
    public void draw() { 
        System.out.println(“RightAngle::draw\n“);
    }

    public void computeCentroid(RightAngled t) {
        System.out.println(RtAngle::centroid\n“);
    }
}

在我的驱动程序中,我有以下代码行:

Triangle tr= new RightAngledTr ();
RightAngledTr rtr= new RightAngledTr ();
tr.computeCentroid(rtr);
tr.draw();
rtr.computeCentroid(tr);

我预期的输出是:

Base::centroid
Base::draw
Base::centroid

但是,我得到的输出是:

Base::centroid
RightAngle::draw
Base::centroid

我的问题是,当tr.draw()调用RightAngleTr类'方法时,为什么tr.computeCentroid(rtr)调用Triangle类'方法?

这没有意义。 Liskov 替换原则似乎不适用。

【问题讨论】:

标签: java inheritance polymorphism overriding


【解决方案1】:

这就是java的工作原理。 draw() 方法被覆盖

查看 oracle documentation 文章以了解这些概念。

子类中具有相同签名(名称,加上其参数的编号和类型)和返回类型的实例方法作为超类中的实例方法会覆盖超类的方法。

Triangle (parent) 持有 RightAngledTr (child) 的引用,并且在子对象上调用 draw() 方法。这称为覆盖功能。

孩子是父母的类型。持有子实例的父级调用子级的重写方法。如果子方法不存在,则调用父方法。

重写 是重新定义具有相同签名的基类(父)行为。如果您在子类中更改基类方法的签名,则称为重载。你对其他方法做了同样的事情:computeCentroid()

但不要期望在父级和子级中声明的相同变量是相同的。

变量不会被覆盖。只有方法被覆盖

【讨论】:

    【解决方案2】:

    您正在对专用对象调用方法 draw。即使你将它包装在基类中,你也会调用被覆盖的 draw 方法。

    【讨论】:

      【解决方案3】:

      computeCentroid() 方法的签名不同。因此,您不是压倒一切,而是重载。

      【讨论】:

      • 他说的是draw()我认为的方法
      • 这就是为什么你总是使用@Override
      • 但是trTriangle类型的对象,那为什么我做tr.draw()时没有调用Triangle类的draw()方法呢?
      • 看看我的回答。
      猜你喜欢
      • 1970-01-01
      • 2020-01-06
      • 2011-12-19
      • 1970-01-01
      • 2012-12-23
      • 2014-05-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多