我有一个抽象类MotherClass
和两个扩展ChildClass1
的抽象类ChildClass2
和MotherClass
。
我希望确保任何扩展MotherClass
的课程实际上都会扩展ChildClass1
或ChildClass2
。我认为基于树的课堂设计出了问题。你知道如何正确地做到这一点吗?
答案 0 :(得分:3)
如果MotherClass
具有包可见性且ChildClass1
和ChildClass2
是公共的并且位于同一个包中,则可以将这两个子类化为子类,而不是母类。
编辑:
另一种可能性:
interface Marker {} //note that this is package private
public abstract class Mother<T extends Marker > {}
public class ChildA extends Mother<ChildA> implements Marker {}
public class ChildB extends Mother<ChildB> implements Marker {}
方法:
doSomething(Mother<?> mother() {}
你现在无法做到
class GrandChild extends Mother<GrandChild> {}
这会编译,但至少会给你一个警告:
class GrandChild extends Mother {} //warning like "Mother is a raw type"
没有警告的方式:
class GrandChild extends ChildA {}
class GrandChild extends ChildB {}
答案 1 :(得分:2)
将它放在MotherClass
:
protected MotherClass() {
if (!(this instanceof ChildClass1 || this instanceof ChildClass2)) {
throw new IllegalStateException("Oh noes!");
}
}
这个(难以置信的丑陋)解决方案的灵感来自SWT,它在Widget
类中有这样的代码:
protected void checkSubclass () {
if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
}
checkSubclass
在Widget
的唯一构造函数中被调用。
这样做是为了避免继承SWT窗口小部件类(因为它不受支持且不应该完成)。请注意,checkSubsclass()
不是 final
。因此,如果您真的想要扩展Button
(并准备好承担后果),您可以将checkSubclass()
覆盖为无操作方法。
答案 2 :(得分:1)
从ChildClass1
和ChildClass2
中提取常用功能,并将其移至MotherClass
或从MotherClass
派生的其他一些抽象类。