【问题标题】:Different Types of Subclass Objects with One Superclass [closed]具有一个超类的不同类型的子类对象[关闭]
【发布时间】:2014-12-02 13:40:07
【问题描述】:

所以我有一个超类 GeoFig 类,以及两个子类 Cylinder 和 Sphere。我想在超类中包含一种方法来计算体积(称为 setVolume),但是每个子类都有不同的计算体积的公式。通过子类的构造函数,我将 setVolume 和 getVolume。我该怎么做?

【问题讨论】:

  • 请显示一些代码。
  • 使用抽象 setVolume() 方法制作 GeoFig 抽象。在子类中,您将提供方法的实现。
  • setVolume 实际上会做什么?
  • @noobforce: "I must have the method in the superclass, with no abstract method." - 那么你的设计是错误的。 GeoFig 是一个抽象概念,它应该是一个抽象类。每个继承的类都有自己的确定音量的实现,因此每个都应该覆盖一个抽象成员来进行确定。此外,应该没有setVolume,因为数量是根据其他指标计算的。
  • @noobforce: "setVolume will make volume equal to whatever the formula for calculating the shape's volume is." - 这没有任何意义。例如,体积为 5 立方单位的圆柱体的尺寸是多少?没有足够的数据来计算。 "GeoFig contains a private double field called volume." - 也不正确。体积不被存储,它是计算出来的。它可以被临时缓存以提高性能(虽然不是真的必要,这些都是小计算)并且当形状的维度发生变化时缓存会失效,但它实际上并没有被存储。

标签: java subclass superclass


【解决方案1】:

我的 Java 非常生锈了,所以这里的任何代码都是伪代码,只是为了演示概念...

您没有正确地在代码中建模对象。代码应该与正在建模的现实世界概念相匹配。因此,让我们考虑一下这些现实世界的概念。

什么是GeoFig

一个人长什么样?如果你手里拿着一个,它会是什么形状?没有答案,因为它不是一个具体的对象。它是一个概念或 抽象 对象。所以它应该是一个抽象类:

abstract class GeoFig { }

哪些属性描述了GeoFig

它有长度吗?一个宽度?半径?不是真的,不。但是为了成为 3 维空间中的对象,我们可以假设它具有体积。我们只是不知道如何计算该体积:

abstract class GeoFig {
    abstract double getVolume();
}

现在我们有了父类。

什么是Cylinder

它是一个有体积的几何对象,所以我们可以从父类继承:

class Cylinder inherits GeoFig {
    public double getVolume() {
        return 0;
    }
}

我们如何计算Cylinder 的音量?

π * r^2 * h

但我们还没有rh...

哪些属性描述了Cylinder

它有一个高度和一个半径。事实上,它必须拥有这些才能存在。所以它需要它们来构建对象:

class Cylinder inherits GeoFig {

    private final double height;
    private final double radius;

    public Cylinder(double height, double radius) {
        this.height = height;
        this.radius = radius;
    }

    public double getHeight() {
        return this.height;
    }

    public double getRadius() {
        return this.radius;
    }

    double getVolume() {
        return 0;
    }
}

(假设不变性。如果您希望能够更改Cylinder 的尺寸,请进行适当的更改。)

现在我们也可以计算体积了:

double getVolume() {
    return Math.PI * this.radius * this.radius * this.height;
}

对任何其他形状重复相同的逻辑过程。

【讨论】:

  • 我明白你现在在说什么。对不起之前的固执。但是,我也应该有一个私人领域卷,我的老师不允许我删除它。他说我需要使用方法覆盖或可能超级或this。我该怎么做呢?这是完全不使用音量字段的唯一方法吗?
  • 另外一个问题,如果子类中具有相同名称和参数的方法被覆盖,是否可以在超类中运行方法?
  • @noobforce:我相信这因语言而异(我对 C# 的经验比对 Java 的经验要丰富得多)以及可能被覆盖的不同方式,所以我不能说拥有绝对的权威。这当然值得测试。可能有一种方法可以从子类的覆盖方法中调用base.methodName()super.methodName() 之类的东西。但请注意不要破坏抽象,通过覆盖具有不同语义含义的方法并模糊父方法的原始含义。
猜你喜欢
  • 2018-03-20
  • 1970-01-01
  • 2013-05-20
  • 2015-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多