[英]Java, how to stop inheriting classes from calling a particular abstract class constructor, apart from one of them?
我有一个抽象类和几个扩展它的具体类。
抽象类有两个构造函数。 我希望其中一个构造函数只能在一个特定的具体类中调用。
(我确实知道Java状态机的enum
模式,但是两级子类化(和不可变的POJO)对于我正在解决的问题更有效。)
public abstract class SuperState {
public final long mValue;
protected SuperState(long value) { mValue = value; }
protected SuperState(SuperState last) { mValue = last.mValue + 1; }
...
}
public class FirstState extends SuperState {
public FirstState() { super(0); }
...
}
public class SecondState extends SuperState {
public SecondState(SuperState last) { super(last); }
...
}
public class ThirdState extends SuperState {
public ThirdState(SuperState last) { super(last); }
...
}
我想让它成为任何子类(除了FirstState
之外)的编译时(或至少运行时)错误,以调用SuperState(long value)
构造函数。
我可以找出在SuperState
构造函数中构造的具体类的类型,如果它不符合预期,则抛出运行时异常吗?
是否有一个抽象类的“首选”具体类,以便它具有某种形式的额外访问?
我想你不清楚你在做什么。 你说SuperState
有一个只能从一个特定实现调用的构造函数。 为什么? 那个子类特别吗? 为什么其他实现不应该这样称呼?
如果FirstState
如此特别,也许您希望将其作为内部类:
public abstract class SuperState {
public final long mValue;
private SuperState(long value) { mValue = value; }
protected SuperState(SuperState last) { mValue = last.mValue + 1; }
...
public static class FirstState {
//Can call SuperState(long) from here
}
}
如果这对您来说不合适,那么您可能应该打开两个构造函数。 如果在我看来,你正在制作一个类似链的结构,那么你可能甚至不希望将FirstState
作为可访问的类:
public abstract class SuperState {
public final long mValue;
private SuperState(long value) { mValue = value; }
protected SuperState(SuperState last) { mValue = last.mValue + 1; }
...
private static class FirstState extends SuperState {
private FirstState() { super(0); }
}
public static SuperState getFirstState() { return new FirstState(); }
}
我能想到的一种方式,虽然我发现它很难看:
protected SuperState(long value)
{
if (!this.getClass().getName().equals("SomeConcreteClassName"))
throw new SomeException ();
mValue = value;
}
虽然Tom关于将FirstState类放在与SuperState相同的包中并使用包私有访问的评论听起来更好。
我认为实现它的唯一方法是使用“朋友”的模拟。 诀窍是在FirstState
拥有私有Value类,只能由FirstState
。 其他类可以看到FirstState.Value
类,但无法实例化它。
abstract class SuperState {
public final long mValue;
protected SuperState(FirstState.Value value) { mValue = value.value; }
protected SuperState(SuperState last) { mValue = last.mValue + 1; }
}
class FirstState extends SuperState {
public static class Value { private Value() {} }
private static Value value = new Value();
public FirstState() { super(value); }
}
class SecondState extends SuperState {
public SecondState(SuperState last) { super(last); }
}
您可以使用默认访问修饰符来执行此操作:
package a;
public abstract class SuperState {
public final long mValue;
SuperState(long value) { mValue = value; } // constructor has default access modifier
protected SuperState(SuperState last) { mValue = last.mValue + 1; }
...
}
package a;
public class FirstState extends SuperState {
public FirstState() { super(0); }
...
}
package b;
// is not able to access constructor SuperState(long) ie. calling contructor
// SuperState(long) will result in compile time error
public class SecondState extends SuperState {
public SecondState(SuperState last) { super(last); }
...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.