class 的构造函数,其 super 只能通过工厂方法创建

Constructor for a class whose super should only be made via factory method

我有以下 class:

public class Foo(){
    int parameter;
    static Set<Foo> cache=new HashSet<Foo>();
    public Foo(int parameter){
        this.parameter=parameter;
        addToCache(this);
    }
    public static Foo Factory(int parameter){
        Foo duplicate=findDuplicate(parameter);
        if (duplicate!=null){
            return duplicate;
        }else{
            return new Foo(parameter);
        }
    }
}

注意直接调用Foo的构造函数会添加到静态缓存。 我现在需要 subclass 这个对象来添加一些功能。

public class Bar() extends Foo{
    public Bar(int parameter){
        //Danger
    }
}

但现在我卡住了。 Bar 的构造函数必须以一种或另一种方式调用 super(),但这不会像 Foo.Factory() 那样检查重复项。

我真正想要的是:

public Bar(int parameter){
    this=Foo.Factory(parameter);
} 

但这显然是无效的java。

现在,我不得不为 Foo 编写一个 hacky 辅助构造函数,它也检查重复项,并让 Bar 使用它:

//Second unused parameter just so the constructors are different
public Foo(int parameter, boolean isEvil){ 
    Foo duplicate= findDuplicate(parameter);
    if (duplicate!=null){
        this.copy(duplicate); //Evilly take on all attributes of duplicate
    }else{
        //Now we have to copy the body of the original constructor. 
        //It has to be kept synched forever, and I can't even call it!
        this.parameter=parameter;
        addToCache(this);
    }
}

Bar(int parameter){
    super(int,true);
}

但这有总是创建新对象的问题,这会导致可变性和散列问题。此外,任何不注意的人都无法看出此构造函数的工作方式不同。

TLDR:如何为 class 创建一个构造函数,其 super 只能通过工厂方法创建。

可能与 this question 重复,但在 java 中(同样该问题只有一个答案,我和 OP 都不满意)

在我看来,你有两个选择。

选项 1 是为 bar 创建工厂方法而不是 public 构造函数。

选项 2 不是让 bar 继承自 foo,而是包含 foo 的实例作为成员。在构造函数中,您可以调用 foo.

的工厂方法

你走哪条路可能取决于细节。