Has-A关系适用于继承的成员?

时间:2009-12-13 22:35:35

标签: java oop

鉴于代码:

class Car{
   Engine engine;
}

class SportCar extends Car{
   SportChair chair;
}

说'SportCar '有“引擎和SportChair”是否有效? 或者唯一有效的肯定是:'SportCar '有一个“ SportChair”和“Car ”有一个“引擎”?

5 个答案:

答案 0 :(得分:3)

我没有任何确切的消息来源,但我的直觉是这种关系适用于继承的成员。

在你的例子中,SportCar“是一辆”汽车,因此它“有一个”引擎。

这可能与Liskov Substitution Principle有关,其中超类型应该可由其任何子类型替换。在这种情况下,超类型“has-a”引擎,为了使子类型遵循LSP,他们必须认识到它们也具有引擎。

这不仅应该遵循类的成员,而且对于一般的行为和状态 - 一个类不应该从另一个继承,除非对每个方面都有意义进行继承。即在你的例子中,如果Car有一个方法“attachBabySeat()”,那么SportsCar继承它就没有意义。同样,成员protected BabySeat[] babySeats对SportsCar没有意义。

Java中的例外是private或“package-private”(也就是默认的)成员变量。这些通常是不属于抽象的实现细节。子类无法访问这些字段,因此我不认为私有成员是子类“has-a”关系的一部分。

就Java语言而言,当创建子类时,也构造超类(隐式或显式)。因此,当超类具有私有成员时,就内存,JVM等而言,它仍然是子类对象的一部分。例如,可以从子类中调用使用私有成员的超类上的方法而没有问题。所以在某种程度上,你可能会认为子类确实是“拥有”超级类的私有字段,但我认为这是在物理层面,而不是概念层面,可以忽略不计。

答案 1 :(得分:1)

如果一辆跑车是一辆汽车而一辆汽车有一个发动机,在我看来,跑车有一个发动机。完全有效。

答案 2 :(得分:0)

取决于 - 我不会在UML图中复制这种关系,但从概念上讲,SportsCar有一个(n)引擎,因为它来自Car。

答案 3 :(得分:0)

是的,SportsCar是一辆汽车,因此有一个引擎。这是composite设计模式的一个示例。

答案 4 :(得分:0)

没有。说SportsCar有一个引擎是无效的。特别是在Engine具有默认访问权限的示例中。我想看看这个的最佳方式如下。

我将使用一个真实世界的例子,我认为这通常有帮助。

驼鹿是一种鹿。

鹿有2只眼,因此驼鹿有2只眼睛。

受伤的驼鹿只有一只眼睛。

受伤的驼鹿是一种驼鹿。