【问题标题】:Subclass as a collection of classes子类作为类的集合
【发布时间】:2013-06-20 04:23:26
【问题描述】:

在 Java 中我们可以拥有(假设额外的构造方法等):

class Car
{
    public void Vrooom() { System.out.print("Vrooom!"); }
}

class Prius extends Car
{
    public void Vrooom() { System.out.print("..."); }
}

class Cars extends Car
{
    private ArrayList<Car> mCars;
    public void Vrooom() { for(Car car: mCars) car.Vrooom(); }
}

我遇到过这样的代码,但Cars 对我来说感觉不对,因为它必须覆盖每个Car 方法来添加for 循环。这是一个反模式吗?如果是,我为什么不这样做?

【问题讨论】:

  • 继承应该代表一个is-a关系。您通常不会说一系列汽车是汽车。
  • 我同意@VaughnCato,通常你会从数组类型(或任何等效的java类)扩展你的Cars类,或者只是使用一个通用列表来代替它(如果你不需要带有辅助方法的强类型表示等)。此外,对于您不应该这样做的原因,通过扩展Car,没有什么可以阻止您将Cars 添加到您的列表中。毕竟,您是在说“汽车就是汽车”。

标签: design-patterns inheritance


【解决方案1】:

您要继承汽车来表示汽车列表?你不需要这样做。如果你只是想要一个汽车列表,那么你可以创建

List<Car> list = new ArrayList<Car>();

继承意味着子类应该通过超类的 IS-A 测试,在您的情况下,汽车列表并不完全是汽车。

【讨论】:

  • 谢谢,“IS-A”是我一直在寻找的表达方式 - 我正在准备幻灯片来描述为什么代码库很糟糕,所以我会添加它。
【解决方案2】:

你是对的,这感觉有些不对劲。在我看来,objects 的集合也不应该扩展 object

您的经销商可能拥有一些汽车,但我认为您会这样做(而且我不会 java,所以我可能会稍微搞砸语法):

class Dealership extends Businesses
{
    private private ArrayList<Car> sellableCars;

    public void itsAHugeSalesSpectacular() {
        for(Car car: sellableCars) car.Vrooom(); 
    }
}

但根据我的经验,您没有理由将经销商的汽车本身定义为一个对象。

【讨论】:

    猜你喜欢
    • 2010-09-25
    • 1970-01-01
    • 2016-11-03
    • 1970-01-01
    • 1970-01-01
    • 2020-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多