我正在使用一个外部库,在那里遇到了我想扩展的公共类。唯一的构造函数是程序包私有的,因此对我不可见。
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)不可见
有什么方法可以扩展此类吗?如果没有,将其宣布为公开目的是什么?
答案 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
原则。