有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java HasA关系是否适用于继承的成员?

鉴于代码:

class Car{
   Engine engine;
}

class SportCar extends Car{
   SportChair chair;
}

说“SportCar有一个发动机和一把SportChair”是正确的吗
或者,唯一有效的确认是:“SportCar“has-a”SportChair”和“Car“has-a”发动机”


共 (5) 个答案

  1. # 1 楼答案

    不,说跑车有发动机是无效的。尤其是在引擎具有默认访问权限的示例中。我想最好的方法是看下面的内容

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

    驼鹿是鹿的一种

    鹿有两只眼睛,所以驼鹿有两只眼睛

    受伤的驼鹿有一只眼睛

    受伤的驼鹿是驼鹿的一种

  2. # 2 楼答案

    是的,跑车是一辆汽车,因此有发动机。这是composite设计模式的一个例子

  3. # 3 楼答案

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

  4. # 4 楼答案

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

    在你的例子中,跑车是一辆汽车,因此它有一个引擎

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

    这不仅适用于类的成员,也适用于一般的行为和状态——一个类不应从另一个类继承,除非继承的每个方面都有意义。例如,在您的示例中,如果Car有一个方法“attachBabySeat()”,SportsCar从中继承就没有意义了。同样地,成员protected BabySeat[] babySeats对跑车来说也没有意义

    在Java中,例外情况是private或“包私有”(又名默认)成员变量。这些通常是不属于抽象的实现细节。子类不能访问这些字段,所以我不认为私有成员是子类“HAS-A”关系的一部分。

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

  5. # 5 楼答案

    视情况而定——我不会在UML图中复制这种关系,但从概念上讲,SportsCar有一个(n)引擎,因为它源于Car