0

假设我有以下课程:

public class BodyClass{

private LegClass myLeftLeg;
private LegClass myRightLeg;
private NoseClass myNose;

...

}

稍后在软件程序的某个深处,我将拥有一个 myRightLeg 的单独实例。

现在,为什么我不会轻易(或根本)知道这个右腿属于哪个 BodyClass 对象,更不用说这个实例变量包含在哪个 Class 中了?为什么在组合关系中,父类的信息不会在运行时自动存储在子对象中?

难道没有一个世界可以让 Java 延迟加载每个类变量以及有关父类本身的信息吗?

为什么这会很糟糕?这不是一个相当可靠的好处吗?

我听到人们说诸如子类之类的东西不应该知道它们的超类,而实例变量不应该知道它们的父类,但坦率地说,我不明白为什么不知道。

我的问题与这个问题有关:

如何在 Java 中找到给定类的所有子类?

4

3 回答 3

1

现在,为什么我不会轻易(或根本)知道这个右腿属于哪个 BodyClass 对象,更不用说这个实例变量包含在哪个 Class 中了?
...
为什么在组合关系中,有关父类的信息在运行时不会自动存储在子对象中?

因为语言规范不包括这个要求。

在 Java 中,对象不包含对其他对象的引用,除非它们被显式地作为字段赋予它们,或者作为继承的字段被隐式赋予它们。而已。如果你想让你的对象知道哪些对象知道它们,你必须自己编程:

class LegClass {
    private BodyClass body;

    void setBody(BodyClass body) {
        this.body = body;
    }
}

class BodyClass {
    // snip...
    void setRightLeg(LegClass rightLeg) {
        this.myRightLeg = rightLeg;
        rightLeg.setBody(this);
    }
}

请注意这在两个类之间引入的紧密耦合。紧耦合通常不是一件好事。

我不明白为什么这特别有用,并且这样的“功能”转向违反 OOP(Java 支持的)的一些原则,例如封装单一责任。知道哪个实例的字段(请记住,没有理由它必须只有一个!)引用它通常是代码异味。

于 2013-09-22T05:03:24.753 回答
1

有很多原因,但我想我会把它缩小到两个大的:

1) 与真实对象不同,Java 对象可以在多个地方。您不一定会称其为“组合关系”,但“组合关系”在 Java 中并不存在。在 Java 中,您的字段引用了其他对象,并且多个位置的多个字段可以指向同一个目标对象。所以在很多情况下,甚至询问“所有者”或“容器”是没有意义的

2)您可以自己安排此类反向引用,但这通常是个坏主意。Leg 类是你放置关于腿的代码的地方。该代码解决了腿部问题,通常不应该关心周围是否有尸体。如果你有全身问题,只有知道身体和腿才能解决,那就在身体课上解决。这就是所谓的“关注点分离”,这是我们组织软件以便我们理解它的主要方式。

于 2016-05-28T16:41:00.320 回答
0

组合意味着有一个继承意味着是一个

示例:汽车有引擎,汽车是汽车

在编程中,这表示为:

class Engine {} // 引擎类。

class Automobile{} // 汽车类,它是 Car 类的父类。

// Car 是汽车,所以 Car 类扩展了汽车类。类汽车扩展汽车{

// Car 有一个 Engine 所以,Car 类有一个 Engine 类的实例作为它的成员。私人引擎引擎;}

于 2016-05-28T16:28:36.883 回答