【问题标题】:Inheritance involving subclass instances within superclass涉及超类中子类实例的继承
【发布时间】:2013-10-08 05:25:28
【问题描述】:

我有一个对象A,在实例化之后,我对其状态进行各种操作。在A 的方法中,我需要创建另一个类的多个实例(称为B)。 B 对象类在很大程度上依赖于A 的大部分状态,并且实例可以影响A 的状态。

问题如下。由于A 已经实例化,并且在调用A 中的方法之前已经对其状态进行了操作,这些方法需要对B 进行任何实例化,因此我如何使用继承来编写B 的类,因为我这样做了不想在B 中调用super()(因为A 已经实例化了)?

我必须在这里将B 的课程与A 的课程结合起来吗?

public class Test {
    public static void main(String[] args) {
        ClassA instanceA = new ClassA(5000000L); //Initial instantiation and state-setting operation to A.
        instanceA.update(); //Try to get A to create B, where B relies on A's new state from previous operations.
    }   
}

class ClassA {
    long tempLong;
    ClassB instanceB;

    public ClassA(long setLong) {
        tempLong = setLong;
    }

    public void update() {
        this.instanceB = new ClassB(); //instanceA needs an instanceB to work with. 
    }

}

class ClassB extends ClassA {
    long tempLong2;

    public ClassB() {
        // I don't want to call super() here because instanceA is already created and instanceA's state is already set!;
        this.tempLong2 = super.tempLong*2; //instaceA's state is necessary for instanceB to function!
    }
}

【问题讨论】:

  • 使用代码,您可以在 2 行中说出您的问题。
  • 你在一个阶段有HAS-A和IS-A关系?就像被问到的问题一样,它真的有意义吗?
  • 您的代码设计有问题。每当我在我的代码中创建一个超类依赖于它自己的一个子类时,我最终发现我需要重构以摆脱依赖。你想用这个来完成什么? (例如,如果每个ClassA 对象在内部需要一个ClassB 对象,那么每个ClassB 对象也需要一个(因为它也是一个ClassA)。这在哪里停止?
  • @TedHopp 我想要的只是一个ClassB,它可以使用instanceA 的所有状态。我不关心它访问ClassA 方法的能力。有这样的功能吗?

标签: java inheritance subclass superclass


【解决方案1】:

您的设计存在根本缺陷。你似乎相信当你打电话给update()

public void update() {
    this.instanceB = new ClassB(); //instanceA needs an instanceB to work with. 
}

新的ClassB 实例与this ClassA 实例相关只是因为ClassB extends ClassA。不,事实并非如此,因为new ClassB() 创建了一个全新的Object,其ClassA 状态与this 不同。

如果 ClassB 依赖于 ClassA 的唯一属性是 temprature,则最好将其传递给构造函数并在此处取消继承(如果 ClassB IS-NOT-A ClassA)。

public void update() {
    this.instanceB = new ClassB(this.tempLong);
}

public ClassB(long tempLong) {
    this.tempLong2 = tempLong * 2;
}

如果依赖项需要访问几乎所有的ClassA 属性,则通过将ClassA 实例传递给ClassB,在此处支持HAS-A 而不是继承可能更有意义。

public void update() {
    this.instanceB = new ClassB(this); // ClassA passes itself
}

public ClassB(ClassA classA) {
    this.classA = classA; // ClassB HAS-A ClassA relationship
    this.tempLong2 = classA.getTempLong() * 2;
}

【讨论】:

  • 在我的现实生活中,instanceA 的状态是巨大的,这就是为什么我尽量不通过构造函数(因为构造函数会有 5 行长!)
  • 在这种情况下更喜欢 HAS-A。您可以访问其所有状态。
  • @Ravi 说得对,你应该“支持组合而不是继承”,一个非常好的信息可以在 Joshua Bloch 的有效 Java 的第 16 条中找到,他解释了为什么支持组合。跨度>
猜你喜欢
  • 2012-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-30
  • 1970-01-01
  • 1970-01-01
  • 2012-06-26
相关资源
最近更新 更多