Как может класс в Python наследовать от 2 возможных суперклассов? - PullRequest
0 голосов
/ 09 апреля 2020

В настоящее время я работаю над платформами в 2D-игре Python. Я создал 1 суперкласс: Block. Я также создал 2 подкласса Block: Solid (прыгать нельзя) и Semi_Solid (прыгать снизу). Теперь я хотел бы добавить класс Platform (для перемещения этих блоков), который наследуется от Solid или Semi_Solid, поэтому его экземпляры могут иметь атрибуты Solid или Semi_Solid.

Итак, как я могу создать экземпляры Platform, которые могут наследоваться от Solid или Semi_Solid? Обязан ли я создавать 2 разных класса?

Итак, я попытался:

class Block:
    pass

class Solid(Block):
    pass

class Semi_Solid(Block):
    pass

x = "solid"

class Platform(Solid if x=="solid" else Semi_Solid):
    pass

obj1 = Platform()
x = "semi-solid"
obj2 = Platform()

Но изменение x не учитывается. Я получил 2 solid платформ

Я сделал несколько других тестов, но ни одна из них не была успешной. Спасибо за любую помощь.

1 Ответ

3 голосов
/ 09 апреля 2020

Наследование, вероятно, является наиболее переоцененной функцией ОО, и, увы, в большинстве вводных публикаций о ОО, как правило, представляется как универсальное решение для всех. Правда в том, что real основные функции OO - это инкапсуляция (которая не является скрытием данных как таковых, а способностью определять автономные компоненты, которые группируют состояние и поведение и абстрактные детали реализации из клиентского кода) и polymorphi c dispatch (возможность использовать объекты разных типов / с разной реализацией единообразным образом с помощью общего API).

На уровне semanti c наследование описывает "is «отношение» - если B наследует от A, то B является A (ср. принцип замещения Лискова ). Итак, ваша «Платформа» - «Solid» или «Полу Solid»? (подсказка: это, конечно, реторетический вопрос).

На уровне реализации наследование, в основном, является фиксированной (stati c) и каким-то образом ограниченной формой составления / делегирования - независимо от того, что не реализовано в дочерний класс делегируется его родителям. Хороший ОО-дизайн основан на отделении ответвлений и отдельных инвариантов от вариантов, делегировании части «варианта» другому объекту. Это подтверждается шаблоном стратегии и его близким родственником шаблоном состояния .

Скорее всего, ответ на ваш вопрос в основном заключается в использовании шаблона Strategy для обработки поведенческих различий между solid и полу solid блоками - в этом случае у вас будет только один единственный класс Block, отвечающий за все, что является общим для всех видов блоков, и стратегии поведения «прыжок через» (и другие возможные поведенческие различия между блоками). Тогда ваш класс Platform - который не обязательно должен быть подклассом Block (может или не может быть правильным дизайном в зависимости от контекста) - примет в качестве аргумента стратегию «скачка» ie (если вы решите сделать это) блок) или экземпляр блока (созданный с помощью соответствующей стратегии ie), если вы решили не делать его подклассом блока.

Это не только решает текущую проблему, но также позволяет добавлять новые стратегии и т. д. c, не касаясь существующего кода, и избегает комбинаторного взрыва классов.

NB: вы можете захотеть получить копию GOF "шаблонов проектирования" Не столько для самого каталога шаблонов (каким бы интересным он ни был), но в основном для первой (длинной) вводной части книги, которая до сих пор является наилучшим доступным текстом по правильному ОО-дизайну.

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