具有不可见构造函数的公共类可以由另一个包中的类扩展吗?

时间:2019-04-23 08:41:34

标签: java java-8 eclipse-cdt

我正在使用一个外部库,在那里遇到了我想扩展的公共类。唯一的构造函数是程序包私有的,因此对我不可见。

public class Token implements IToken {
    Token(int kind, Object source, int offset, int endOffset) {
        ...
    }
    ...
}

我的子类是

public class MyToken extends Token {
    ...
}

出现错误:

  

默认的构造函数未定义隐式超级构造函数Token()。必须定义一个显式构造函数

当我添加一个构造函数时:

MyToken(int kind, Object source, int offset, int endOffset) {
    super(kind, source, offset, endOffset);
}

我收到错误消息

  

构造函数Token(int,Object,int,int)不可见

有什么方法可以扩展此类吗?如果没有,将其宣布为公开目的是什么?

5 个答案:

答案 0 :(得分:2)

任何子类都必须能够访问至少一个基类的构造函数。

如果希望子类存在于另一个包中,则必须使构造函数至少为Token

由于它来自第三方库,因此他们似乎不希望您继承protected的子类。子类化可能是您在这里需要做的另一种选择。

当您(库作者)需要控制实例的创建方式(例如实现单例或强制使用工厂方法)时,不提供公共构造函数是常见的模式。

  

如果没有,将其宣布为公开目的是什么?

可以在任何地方使用公共类,即,您可以在给定的实例上调用方法(即使您自己不能创建新实例)。

答案 1 :(得分:2)

带有受限制的构造函数的 public 类的目的可以是将构造保留给朋友类或静态工厂(创建)方法。

在这种情况下,可能是这种工厂模式。然后您可以使用:

public class MyToken implements IToken {
    private Token delegate;

    public MyToken(int kind, Object source, int offset, int endOffset) {
        // Factory usage:
        delegate = Token.create().withKind(kind).withSource(source)...;
    }

    public int getKind() {
        return delegate.getKind();
    }

    ...

否则,您可以在{em>相同的包中创建与Token相同的包,并使用public构造函数。 对于模块化Java> 8,将不再允许使用此技巧。

我个人的猜测是,Token将由同一包中的某些Parser / Scanner类创建。实际上,甚至可以返回Token的子类,因为它可以是嵌套的内部类,可以访问Parser容器的字段,例如line作为String,filePath

创建自己的IToken实现可能是最好的实现。

答案 2 :(得分:1)

。不更改[(word_feats(neu), 'neu') for neu in mylist if neu not in voc] 类是不可能的。

某些库可以在运行时修改类,但我强烈建议您不要这样做。

答案 3 :(得分:1)

允许使用令牌,但不能创建令牌。例如,这种构造意味着您可能在程序中使用以下内容:

List<Token> tokens = stream.getTokens();

因此基本上,库将创建令牌,您可以使用它们,但不能扩展或创建自己的令牌。

答案 4 :(得分:1)

使用public构造函数构造类protected时,您的观点是正确的,但是您可以尝试通过组合来实现所需的功能,其中MyToken类包含对Token类的引用。这样,我们也将遵循Composition over Inheritance原则。