Можно ли предотвратить переопределение метода путем снижения класса до суперкласса? - PullRequest
0 голосов
/ 17 января 2012

Я пытаюсь понять, одинаков ли ответ на следующий вопрос на всех основных языках ООП; а если нет, то чем эти языки отличаются.

Предположим, у меня есть класс A, который определяет методы act и jump; метод act вызывает метод jump. Подкласс A B переопределяет метод jump (т.е. соответствующий синтаксис используется для обеспечения того, чтобы при вызове jump использовалась реализация в классе B).

У меня есть объект b класса B. Я хочу, чтобы он вел себя точно так же, как если бы он был класса A. Другими словами, я хочу, чтобы jump был выполнен с использованием реализации в A. Какие у меня варианты на разных языках?

Например, могу ли я достичь этого с помощью какой-либо формы удушения? Или, возможно, путем создания прокси-объекта, который знает, какие методы вызывать?

Я бы не хотел создавать новый объект класса A и тщательно настраивать разделение внутреннего состояния между a и b, потому что это, очевидно, не на будущее и не сложно. Я также хотел бы избежать копирования состояния b в новый объект класса A, потому что может быть скопировано много данных.

UPDATE

Я задал этот вопрос специально о Python , , но, кажется, этого невозможно достичь в Python и технически это можно сделать ... вроде ...

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

Ответы [ 4 ]

2 голосов
/ 17 января 2012

Комментарии повторяются: предпочитайте композицию наследованию.

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

Композиция обычно является лучшим решением.Передача изменяющегося поведения вашего объекта другому объекту (или объектам) может уменьшить или устранить вашу потребность в создании подклассов.

В вашем случае поведенческие различия между классом A и классом B могут быть инкапсулированы в шаблоне Strategy.Затем вы можете изменить поведение класса A (и класса B, если он все еще требуется) на уровне экземпляра, просто назначив новую стратегию.

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

1 голос
/ 17 января 2012

То, что вы спрашиваете, совершенно не связано / не поддерживается ООП программированием.

Если вы создаете подкласс для объекта A с классом B и переопределяете его методы, когда создается конкретный экземпляр B, тогда с ним связывается вся переопределенная / новая реализация базовых методов (либо мы говорим о Java или C ++ с виртуальными таблицами и т. д.).

Вы создали объект B.
Почему вы ожидаете, что вы могли бы / могли / должны иметь возможность вызывать метод суперкласса, если вы переопределили этот метод?

Вы можете назвать это явно, например, например. вызывая super внутри метода, но вы не можете сделать это автоматически, и приведение также не поможет вам сделать это.

Я не могу представить, почему вы хотели бы сделать это.
Если вам нужно использовать класс A, тогда используйте класс A.
Если вам нужно переопределить его функциональность, используйте его подкласс B.

0 голосов
/ 17 января 2012

На самом деле вы можете сделать это с Python (вроде), с некоторыми ужасными взломами.Это требует, чтобы вы реализовали что-то вроде оболочек, которые мы обсуждали в вашем первом специфичном для Python вопросе, но как подкласс B .Затем вам также необходимо реализовать прокси-запись записи (объект-обертка не должен содержать состояния, обычно связанного с иерархией классов, он должен перенаправлять доступ всех атрибутов к базовому экземпляру B.

Но скореечем перенаправить поиск метода на A и затем вызвать метод с обернутым экземпляром, вы вызовете метод, передающий объект-оболочку, как self. Это допустимо, потому что класс-обертка является подклассом B, поэтому экземпляр обертки являетсяэкземпляр классов, чьи методы вы вызываете.

Это будет очень странный код, требующий от вас динамического генерирования классов, используя отношения IS-A и HAS-A одновременно.довольно хрупкие и приводят к странным результатам во многих сложных случаях (как правило, вы не можете написать 100% совершенные классы-обертки на Python именно потому, что такая странная вещь возможна).

Я полностью оставляю в сторонепогода это хорошая идея или нет.

0 голосов
/ 17 января 2012

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

Взгляните на статью в Википедии о Виртуальные функции , которая дает полезный обзорподдержки виртуальных функций во многих языках программирования.Это даст вам возможность начать с рассмотрения конкретного языка, а также компромиссы, которые необходимо учитывать при рассмотрении языка, на котором программист может контролировать поведение диспетчеризации (см., Например, раздел C ++).

Итак, ответ на ваш вопрос звучит так: «Нет, поведение не одинаково во всех языках программирования».Кроме того, не существует независимого от языка решения.C ++ может быть вашим лучшим выбором, если вам нужно поведение.

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