Java中的继承和多态

Aks*_*mle 5 java polymorphism inheritance overriding

我有 2 个班级:TriangleRightAngledTr. RightAngledTr继承自Triangle. 代码如下:

Triangle类:

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

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

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“);
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的 Driver 程序中,我有以下几行代码:

Triangle tr= new RightAngledTr ();
RightAngledTr rtr= new RightAngledTr ();
tr.computeCentroid(rtr);
tr.draw();
rtr.computeCentroid(tr);
Run Code Online (Sandbox Code Playgroud)

我期望的输出是:

Base::centroid
Base::draw
Base::centroid
Run Code Online (Sandbox Code Playgroud)

但是,我得到的输出是:

Base::centroid
RightAngle::draw
Base::centroid
Run Code Online (Sandbox Code Playgroud)

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

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

Rav*_*abu 1

这就是java的工作原理。 重写draw()方法

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

子类中的实例方法与超类中的实例方法具有相同的签名(名称,加上其参数的数量和类型)和返回类型,该实例方法将覆盖超类的方法。

TriangleRightAngledTr(parent) 持有(child)的引用,并且draw()在子对象上调用方法。这称为压倒一切的功能。

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

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

但不要期望在父级和子级中声明的相同变量具有相同的效果。

变量不会被覆盖。仅重写方法