Идея состоит в том, чтобы создать DOM-подобное дерево. Но есть некоторые ограничения, что только некоторые типы могут содержать другие.
Я хочу использовать интерфейс | абстрактный класс | суперкласс для реализации некоторых хорошо известных js-функций, таких как appendChild, replaceChild и т. Д.
Я использую страницу классов, блок и элемент, где страницы могут содержать блоки, а блоки могут содержать либо блоки, либо элементы.
Пример: страница - это веб-страница, блок может быть элементом списка, а элемент может быть элементом элемента списка.
Но эти объекты содержат больше, чем просто html-данные, и концепции выходят за рамки простого представления HTML. Это общая идея управления элементами, независимо от того, имеют ли они фактическое представление или являются просто абстрактными объектами. Сама концепция работает для многих различных иерархий.
Чего я хочу добиться, так это повторно использовать как можно больше кода родительского класса (добавление дочернего элемента в основном одинаково для всех классов), но различать подсказки типов для соответствия разрешенным типам, добавляемым как дочерний. 1013 *
Есть четыре основных способа, которыми я себя узнал:
- Я использую интерфейс, который позволяет мне вводить подсказки для суперкласса, но не изменять их.
- Я использую суперкласс с открытыми методами, чтобы я мог переопределить подсказки типов (что полностью противоречит обычной практике при наследовании предварительных условий).
- Я использую суперкласс с защищенными методами, который кажется довольно странным.
- Я избавляюсь от любого суперкласса и просто определяю почти один и тот же класс несколько раз.
- Я использую метод для проверки типа, несмотря на возможность подсказок типа.
Итак, если кто-то все еще хочет ответить, я рад любому предложению, идее или подсказке, какой вариант выбрать. Я надеюсь, что смог бы описать проблему достаточно хорошо.
И если я что-то пропустил, я рад это слышать;)
Код
Способ суперкласса (работает, но нарушает практику наследования предусловий)
class Base {
public|protected function appendChild(Base $child) {
// do stuff
}
}
class Block extends Base {
public function appendChild(Block $child) {
parent::appendChild($child);
}
}
Способ интерфейса (не работает. Не должен)
interface Interface1 {
public function appendChild(Base $child);
}
class Base implements Interface1 {
public|protected function appendChild(Base $child) {
// do stuff
}
}
class Block extends Base{
public function appendChild(Block $child) {
parent::appendChild($child);
}
}
Отредактированные части выделены жирным шрифтом