如何防止其他类创建一个类的实例?

4

我有一个案例,其中包含三个类,分别是SourceFactory、Source和SourceTypeI。我希望只在SourceFactory中创建SourceTypeI的实例。换句话说,在SourceFactory之外,其他类都不能创建SourceTypeI的实例。我该如何防止其他类可以创建SourceTypeI呢?

预期使用方式:

  SourceFactory sF = new SourceFactory();
  Source source = sF.createSource();

  // from there, I should reach methods of SourceTypeI via source
  source.whoIs();

  |-------------|           |-----------------------|
  |SourceTypeI  |           |SourceFactory          |
  |-------------|           |-----------------------|
  |+whoIs():void|           |+createSource():Source |
  |             |           |                       |
  |-------------|           |-----------------------|

  |-----------------------------|
  |    Source                   | <- Source cannot be instantiated, it is used just a 
  |-----------------------------|    for referencing instance of SourceTypeI 
  |                             |
  |-----------------------------|

3
是要限制 Source(如代码所示)还是 SourceTypeI(如文本所述)? - laune
2个回答

1
如果我理解你的问题,你可以将SourceFactorySourceTypeI放在同一个包中。然后使SourceTypeI是final。接下来给SourceTypeI提供包级别(默认)构造函数。
SourceTypeI() { // <-- not public, not private, not protected.
  super();
}

那就不要把“任何其他类”放在该包中。

我还需要在其他两个类中写些什么,这样我才能通过Source类访问到SourceTypeI方法吗?或者我需要再写些东西吗? - user3815954
@Zmavus 将 SourceTypeI 的方法设为公共的,但不要将构造函数设为公共的! - Elliott Frisch

1
抱歉更改名称。
public interface Restricted { // Source
    public int getX();
}

public class Restrict {  // SourceFactory
    private class RestrictedImpl implements Restricted {
        public int getX(){ return 42; }
    }

    public Restricted createRestricted(){
        return new RestrictedImpl();
    }
}

Restrict restrict = new Restrict();
Restricted restricted1 = restrict.createRestricted();

感谢您的回答。RestrictedImp类可以有自己的文件,因为可能需要实现RestrictedImpTypeII。如果我将这两个类放在Restrict中,整体代码质量会降低。 - user3815954
1
你在Java中可以实现的可见性限制是有限的。Elliots提到的使用package可能是你必须走的路。另一方面,你可以将另一个Source/Restricted的实现包装成另一个包装器,并仍然拥有一个单一的工厂将createXyz委托给各个包装器,这样客户端就不会受到影响。 - laune
Java中是否有类似于C++中的friend关键字?也许,我可以通过类的友元方法来实现。 - user3815954

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接