鉴于代码:
class Car{
Engine engine;
}
class SportCar extends Car{
SportChair chair;
}
说'SportCar '有“引擎和SportChair”是否有效? 或者唯一有效的肯定是:'SportCar '有一个“ SportChair”和“Car ”有一个“引擎”?
答案 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只眼睛。
受伤的驼鹿只有一只眼睛。
受伤的驼鹿是一种驼鹿。