Как я заявил в комментариях: если вы действительно можете ограничить входные и выходные данные подтипами базового ввода и базового вывода, я не вижу никаких проблем с этой моделью.
Если под нарушением вы подразумеваете, что при ограничении параметров ввода подкласс больше не может использоваться везде, где может использоваться базовый класс, я бы сказал, что это тот случай, когда вы принимаете принцип замены Лискова как догму, где это должен быть очень хороший совет.
Видите ли, принцип Лисков.. является хорошим руководством и немного упрощенным, так как он даст вам действительно хорошее представление о том, каким должно быть наследование.
Но в реальных условиях ограничение входных параметров (и типов атрибутов) не во всех случаях является проблемой. В любом случае, конкретный пример сослужит нам хорошую службу: подумайте об абстрактном классе Vehicle с методом board, который позволяет вам садиться в Transportables, а конкретные Transportables и некоторые допустимые подклассы Transportable — это Persons, Dogs, Grocery Bag, Pianos и Слоны. Если ваш класс Транспортного средства — Корабль, он может взять все это. Если класс вашего транспортного средства — «Автомобиль», некоторые из них отсутствуют.
Кажется, это ваш вариант использования.
Так что, конечно, вы нарушаете принцип здесь. Формулировка в большинстве мест, объясняющая это, заключается в том, что если вы замените экземпляр подкласса везде, где появляется суперкласс, программа не должна сломаться. Таким образом, наиболее правильным будет модифицировать контракты суперкласса таким образом, чтобы любой вход может или не работал, и позволить ему вызывать исключение во время выполнения ( или вернуть объект, сигнализирующий об ошибке), даже если ввод действителен.
Каждый, кто вызывает этот метод, должен обрабатывать состояние «не работает» — в приведенном выше примере легко увидеть, что если у меня есть метод в несвязанном классе, который вызывает vehicle.board
, он должен быть ответственным за то, чтобы он не пытался поместить внутрь слона. машина. Если везде вызывается метод, то эти проверки выполняются, принцип соблюдается!
Если разработка этого является излишним для любой вашей задачи, я бы сказал ... практичность превосходит чистоту в этом случае, и просто установите аннотации, чтобы отключить проверку статического типа.
Конечно, рассказать об этом средству проверки статического типа - это другое дело - я думаю, что использование Generics, как указано в ответе, указанном в комментариях, может сделать: Как мне аннотировать тип параметра abstractmethod, когда параметр может иметь любой тип производным от определенного базового типа?
person
jsbueno
schedule
11.03.2021