Лучший способ применить наследование и повторное использование кода - PullRequest
0 голосов
/ 05 февраля 2020

У меня есть вопрос относительно лучшего способа структурирования кода для повторного использования с наследованием в тех случаях, когда некоторые методы в базовом классе не имеют смысла в классе наследования. Я думаю, что это общая OOP проблема, а не только особенность, связанная с TypeScript ...

Так что в принципе в некоторой форме псевдокода проблема похожа на эту:

class BaseClass делаетSenseForA делает SsenseForA .... не делаетMenseSenseForA не делает MenseSenseForA ....

Как тогда иметь Class A наследовать BaseClass. Просто прямое наследование означает, что Class A будет иметь методы-члены, которые на самом деле не имеют смысла.

Не использование наследования означает, что код будет дублирован как в BaseClass, так и Class A

* 1015. * Перемещение makesSenseForA методов во внешний класс с обоими BaseClass и его дочерним классом зависит от этого извлеченного класса (ie с использованием композиции), не работает в этом конкретном сценарии, потому что извлеченный класс должен фактически рассматриваться как A BaseClass.

Как лучше всего справиться с такой OOP ситуацией моделирования?

РЕДАКТИРОВАТЬ: из-за отсутствия лучшего примера это все равно, что пытаться смоделировать Human и Cyborg - эти два разделяют тонну загрузок аналогичной реализации, и, следовательно, первая мысль может состоять в том, чтобы иметь Cyborg extends Human ...

Но также будет тонна реализации, которая Human имеет то, что Cyborg не должно иметь.

Отказ от наследования означает, что аналогичные функциональные возможности придется дублировать в Human и Cyborg`.

И композиция также не работает, потому что если вы извлекаете те реализации, которые похожи, в отдельный объект, этот объект и его метод будут иметь свойство Human, и, следовательно, должны быть замеченным как Human в нашем моделировании.

Ответы [ 2 ]

3 голосов
/ 05 февраля 2020

Да, это действительно общая проблема. Но ваш пример не очень точная ссылка на наследование. В основном мы используем наследование не из-за общих функций. Общие функции, для их повторного использования, могут быть записаны как классы утилит / утилит. Вы наследуете класс, когда он в основном является подтипом родительского класса, и мы создаем интерфейсы для вещей, которые не являются реальными объектами, а являются типом. Например:

  • Интерфейс: Животное
  • Класс: Тигр реализует Животное
  • Класс: Козел реализует Животное

Обратите внимание, что Animal как таковой не может быть объективирован. Теперь, хотя многие функции обоих классов Goat и Tiger будут общими, но ни один не должен расширять другой, так как метод hunt() не будет иметь смысла для класса Goat, и graze() won ' Не имеет смысла для Tiger. Для этого мы используем интерфейсы. Теперь, чтобы переместить обычные функции в тот же класс, вы можете дополнительно разбить эту модульность следующим образом:

  • класс Плотоядное животное расширяет Animal
  • Класс Herbivore расширяет Animal

Нет коричневых ie баллов, чтобы угадать, что Goat и Tiger будут реализованы сейчас. В случае, если есть общие функции, которые вы по какой-то причине не можете записать в класс Animal, вы можете написать их как утилиту. Предположим, у вас есть робот-козел c, который имеет много общих функций с настоящим козлом, вы не extend Goat, но перемещаете общие функции как утилиту, скажем GoatUtilities.

Редактировать: Кто-то указал, что служебные классы не совсем OOP, а процедурные ... Но они определенно могут дополнить ваши классы, чтобы помочь им следовать OOP правильным путем. Вот почему они "полезные" классы. Итак, вот что упущено, и я попытался указать на то, как наследование было неправильно истолковано / неправильно использовано в данном примере, который каким-то образом привел к проблеме, которая как бы нарушила принципы OOP. Наличие жизнеспособного объектно-ориентированного дизайна не означает, что вы не должны использовать служебные классы, потому что цель состоит в том, чтобы применить наследование и повторное использование кода.

0 голосов
/ 05 февраля 2020

Если вы делаете метод закрытым, он будет использоваться только в этом классе. Если вы сделаете его защищенным, его можно будет использовать во всех подклассах. Таким образом, методы, которые не имеют смысла в Class A, должны быть закрытыми, остальные должны быть защищены или опубликованы c.

В java вы можете узнать об этом подробнее здесь .

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