【问题标题】:Is it possible for two child-classes to work together两个子班可以一起工作吗
【发布时间】:2021-08-12 11:10:10
【问题描述】:

我有一个名为 Product 的基类。 “Drink”和“Pizza”类是从“Product”类继承的子类。 我还有一个名为“Ingredient”的类,它是 Pizza 类的一部分,因此 Pizza 类应该有一个 Ingredient 类的实例(列表)。

我的问题是: 由于成分与所有其他“产品”具有相同的属性,它是否也可以在与“披萨”子类一起工作时从“产品”类继承?

【问题讨论】:

  • 如果 Ingredient 类扩展了 Product 类指定的核心功能(相同的属性、相同的方法签名等),它应该从 Product 继承。但是,如果 Products 具有/定义不代表成分的成员(例如,如果 Product 有一个名为 SellToCustomer() 的方法,您不想将其应用于比萨成分),则 Ingredient 类不应继承来自ProductPizzaIngredient 是否保留彼此的引用并“一起工作”是完全不同的事情。
  • 做对你更有意义的事。在您的业务环境中,一种成分可以被视为一种产品吗?如果是这样,那么您也希望它成为一种产品。
  • 也许您可以创建一个项目,并且产品和成分/材料都从它继承,作为产品可以出售,而成分/材料用于创建产品。无论如何,你应该做有意义的事。如果您没有预见到合理的收益,也不要过度设计。
  • 这似乎是教授面向对象的典型示例。但通常继承并不是最好的方法。 wizards and warriors 上的 Eric lipperts 文章可能会很长但很有用。
  • 这个问题在 OOP 上下文中似乎是编程语言中立且相关的。 (我已经更新了标签)并且足够清楚可以回答。因此,我建议重新打开它。

标签: oop inheritance uml class-diagram class-design


【解决方案1】:

是的,他们可以!

是的,从同一个超类继承的类可以完美地协同工作。没有不兼容。甚至还有一种设计模式在同一个类上使用这两种关系(composite pattern)。

备注:“一起工作”这个词有点含糊,可能意味着不同的东西。但是您的类图足够精确,表明您的意思是可能的关联。

但是怎么做呢?

您的图表显示了PizzaIngredient 之间的可导航关联(空心箭头)。这意味着实施应确保比萨饼可以轻松找到其成分。

在您的叙述中,您提到了一个列表。我知道一个Ingredient 可以在没有任何Pizza 的情况下存在,但一个Pizza 可以有多个Ingredient。通过在关联的Ingredient 一侧指明*,在图表上指定这种多重性很重要。

反方向的关系仍有一些谜团:

  • 未指定可导航性:我们不知道Ingredient 是否能够轻松找到相关的披萨,或者这是否不相关。您可以使用相反方向的箭头(可导航)或横穿线的 X (不可导航)进一步指定这一点。您有权不指定此内容并稍后再决定。可导航性对类可以协同工作的方式产生影响:这意味着Pizza 可以“使用”成分(例如,将其用作操作中的参数,直接调用成分操作等...)。但是,在相反方向上缺乏导航性意味着Ingredient 本身无法启动与其比萨饼的合作。
  • 更重要的是多样性:我们不知道一种成分是否只与一个披萨相关联 (0..1),或者它是否可以在多个披萨之间共享 (0..*)。了解这一点非常重要,因为实现会非常不同(在后一种情况下,您将拥有多对多关联)。

过度概括?

当人们发现 OOP 时,继承是很诱人的。然而,继承有很多含义、限制和后果。因此,请明智地使用它。

一个有用的建议是开始考虑 A 从 B 继承,前提是 A 是更专业的 B,或者相反,B 是 A 的更一般化。仅仅因为某些属性或操作共享而使用继承是危险的同名。顺便说一下,名称可能会产生误导。

就您而言,我将Product 理解为公司以给定价格出售的东西:DrinkPizza、可能是AntipastiPasta。所示价格是客户要求的价格。因此,我想知道是否将Ingredient 出售给客户。一种成分可能有价格,但它是购买价格。购买价格与销售价格不同:假设一家餐厅将一些非常特别的披萨分包出去:销售价格与购买价格不同。

当然,如果你的Product是比较笼统的东​​西,在商业意义上,如果它可以有销售价格和购买价格,并且不一定在菜单上,那么没问题,继续。但请注意,此类通用产品的管理要复杂得多(例如,这里有一个著名的ERP example,有 20 多个不同的屏幕来管理产品的所有方面)。

其他说明

一个非常常见的建议是prefer composition over inheritance。这个经验法则旨在提醒我们在使用继承之前要三思而后行。让我们明确一点,以防万一:这并不意味着继承和组合不兼容。

【讨论】:

  • 只是一个哲学问题:Ingredient 的多重性应该是2..* 吗? * 仅表示任何,包括无。嗯,没有配料的比萨绝对不是比萨。但即使有一个,它只是成分,不是吗?所以最低限度应该是2 才能让它变得新,对吧?
  • 就在您完成回复之前 :-) 建模是如何开始幻想的,这很有趣!
  • @qwerty_so 这确实是一个非常相关的问题。如果你数一下外壳并考虑到外壳本身不是很好吃,我们可以推断出 2 是最低限度的。我最喜欢的比萨饼自己用至少 3 种成分制作他的面包皮,这使得比萨饼至少由 4 种成分组成。但如果你想支持分包(或更糟糕的是,去凝结),比萨饼可以由单一成分制成。现在,为了支持创造力,你必须接受老板刚刚发明了一种只能在今晚出售的新披萨,但行政文员还不能进入收据。(1/2)
  • @qwerty_so 所以为了支持这种灵活的商业模式(是的,不是很工业化,但很有品位和充满惊喜)你需要接受零成分的最低广告,承认它可能是暂时的,或者如果第二天酋长认为这不是她所期望的烹饪艺术的总和并决定尝试另一个新的特殊收据,则可以确定)。我喜欢这种哲学问题。 (2/2)
  • 每个披萨的基础是面团,它本身是由水、橄榄油、酵母、盐和面粉制成的(我每个星期六都做)。当然,人们可以买一个现成的面团,使其成为一种成分,但我不会。此外,作为单一“成分”的(冷冻)比萨饼也是禁止使用的!
猜你喜欢
  • 1970-01-01
  • 2010-09-14
  • 2012-10-29
  • 2013-07-09
  • 2016-01-29
  • 2017-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多