Как заставить реализующий класс наследовать от того или иного подкласса? - PullRequest
2 голосов
/ 17 марта 2011

У меня есть абстрактный класс MotherClass и два абстрактных класса ChildClass1 и ChildClass2, которые расширяются MotherClass.

Я хочу убедиться, что любой класс, расширяющий MotherClass, действительно расширитChildClass1 или ChildClass2.Я чувствую, что что-то не так в моем древовидном дизайне классов.Вы видите, как это сделать правильно?

Ответы [ 3 ]

4 голосов
/ 17 марта 2011

Если MotherClass имеет видимость пакета, а ChildClass1 и ChildClass2 являются общедоступными и находятся в одном пакете, вы можете создать подкласс этих двух, но не MotherClass.

Редактировать:

Другойвозможность:

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 {} 
2 голосов
/ 17 марта 2011

Поместите это в конструктор 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() как неактивный метод.

1 голос
/ 17 марта 2011

Извлеките общие функции из ChildClass1 и ChildClass2 и переместите их в MotherClass или другой абстрактный класс, производный от MotherClass.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...