Использование Java [Интерфейсы / Абстрактные классы] [дубликат]

Этот вопрос уже имеет ответ здесь:

В последнее время я решил смотреть на Java, таким образом, я все еще довольно плохо знаком с ним и также с подходом программирования OO, таким образом, я хотел получить некоторые вещи прямо перед узнаванием больше, (я предполагаю, что он не никогда скоро для запуска с хороших методов).

Я программирую немного 2D игры на данный момент, но я думаю, что мой вопрос относится к любому не тривиальный проект. Для простоты я обеспечу примеры от своей игры.

У меня есть различные виды зомби, но у них всех есть те же атрибуты (x, y, здоровье, нападите и т.д.), таким образом, я записал интерфейс Zombie, который я реализую WalkingZombie, RunningZombie TeleportingZombie и т.д. Действительно ли это - лучшая вещь сделать? Я имею лучше с абстрактным классом? Или с суперклассом? (Я не планирую частично реализовать функции - для этого мой выбор для интерфейса вместо абстрактного класса),

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

Я надеюсь, что этот вопрос не будет оценен как субъективный, потому что я думал, что опытные программисты не не согласятся об этом виде темы начиная с использования интерфейсов / суперклассы / абстрактные классы следуют логическим правилам и являются, таким образом, не просто личным выбором.

25
задан John Saunders 20 November 2012 в 18:43
поделиться

9 ответов

Интерфейс можно рассматривать как «контракт». Вы определяете набор методов, которые должны реализовывать классы, реализующие этот интерфейс.

Абстрактный класс, с другой стороны, используется, когда у вас есть некоторый код, который может быть общим для всех дочерних классов, которые вы хотите реализовать.Таким образом, у вас может быть абстрактный класс Shape, который имеет общий код, а в ваших производных классах (Circle, Square и т. Д.) У вас может быть код, специфичный для этих фигур ( getArea будет пример). Но что-то вроде цвета может быть общим для всех фигур, поэтому вы можете поместить метод getColor в свой абстрактный класс Shape.

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

Эти концепции снова и снова используются в объектно-ориентированном стиле, поэтому важно их понимать. Кажется, вы на правильном пути :).

Итак, если ваш класс зомби имеет какое-то общее поведение, применимое ко всем типам зомби, это звучит как хороший кандидат на роль абстрактного класса. Вы также можете рассмотреть возможность создания интерфейса (возможно, интерфейса GameCharacter ), если у вас есть другие персонажи в вашей игре (возможно, UndeadMice или что-то в этом роде :)). Тогда ваш абстрактный класс Zombie и абстрактный класс UndeadMouse будут реализовывать интерфейс GameCharacter .

16
ответ дан 28 November 2019 в 21:46
поделиться

Если есть сомнения, я выбираю следовать парадигме GOF.

Инкапсулируйте то, что меняется : - Определите уникальное поведение в своем собственном классе. Чтобы сослаться на приведенный выше пример, реализуйте поведение для ходьбы, бега и телепортации в отдельном классе. Таким образом реализуется полиморфное поведение.

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

4
ответ дан 28 November 2019 в 21:46
поделиться

Я бы написал Zombie как абстрактный класс, чтобы избежать переопределения полей x, y, здоровья и т. д.

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

1
ответ дан 28 November 2019 в 21:46
поделиться

Я не думаю, что в вашем случае ваш интерфейс и структура классов хорошо согласуются с реальностью. Фактически, я считаю (поправьте меня, если я ошибаюсь), что каждый зомби может ходить, бегать, телепортироваться и т. Д. В зависимости от того, где он находится.

Следовательно, у вас должен быть класс или интерфейс зомби и действия, которые изменяют состояние зомби. Действие, вероятно, будет интерфейсом или абстрактным классом, так что вы можете применить любое действие к зомби, не зная, что именно делает действие (например, action.perform (zobie) ).

Если у вас есть разные виды зомби, такие как трехногие зомби и однорукие зомби, вы можете реализовать разные классы, которые обрабатывают зомби, такие как отображение себя или проверка изменений состояния (например, особый вид зомби не могут согласиться на телепортацию).

0
ответ дан 28 November 2019 в 21:46
поделиться

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

Допустим, у вас есть метод Move , который заставляет зомби ходить, бегать зомби и т.д. вынудить вас дублировать код, так как вы не можете поместить тело в интерфейс.

0
ответ дан 28 November 2019 в 21:46
поделиться

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

0
ответ дан 28 November 2019 в 21:46
поделиться

Никто не согласен с использованием интерфейсов вместо супер / абстрактных классов;)

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

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

1
ответ дан 28 November 2019 в 21:46
поделиться

У меня есть разные виды зомби, но все они имеют одинаковые атрибуты (x, y, здоровье, атака и т. д.), поэтому я написал интерфейс Zombie, который я реализую с помощью WalkingZombie, Запуск зомби, телепортация, зомби и т. Д. Это лучшее, что можно сделать? Мне лучше с абстрактный класс? Или с суперклассом?

абстрактный класс будет суперклассом для ваших зомби. интерфейс также в некотором смысле был бы суперклассом (суперинтерфейсом?) для ваших зомби.

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

(Я не планирую частично реализовывать функции - поэтому я выбрал интерфейс вместо абстрактного класса)

не уверен, что вы имеете в виду.

, если у вас были разные виды монстров (гоблины, орки и т. Д.)) вы можете найти общее для них поведение, которое хотело бы принадлежать разным базовым классам. это предложит интерфейс.

Я бы начал с абстрактного базового класса и посмотрел, что код говорит вам, когда вы его пишете.

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

ваш выживший - это так называемый игрок-персонаж (в отличие от неигрового персонажа - кто-то в игре, который обычно не атакует вашего выжившего).

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

, так что, возможно, это скорее аргумент в пользу интерфейса .

см .:

Использование наследования и полиморфизма для решения общей игровой задачи Примеры диаграмм классов для RPG (ролевая игра) проектирование иерархии классов для типичных персонажей в ролевой игре

1
ответ дан 28 November 2019 в 21:46
поделиться

Да, я думаю, вы идете по правильному пути, предлагая интерфейсы вместо абстрактных классов.

Любой конкретный зомби, которого вы, возможно, захотите создать, может обладать любой комбинацией функций ходьбы, бега или телепортации, которые вы захотите реализовать.

Я думаю, что современная теория программирования в максимально возможной степени препятствует наследованию, потому что оно препятствует повторному использованию и гибкости в долгосрочной перспективе. Скорее используйте интерфейсы и композицию для достижения гибкости без «тесной связи».

Одна из методик повторного использования кода без наследования: вы можете применить парадигму «Предпочтение композиции перед наследованием».

Мне нравится думать, что «Эффективная Java» Джоша Блоха (2-е издание) можно рассматривать как «современное мышление» ...

http://books.google.com/books?id=ZZOiqZQIbRMC&pg=RA1-PA71&lpg = RA1-PA71 & dq =% 22Bloch% 22 +% 22Effective + java: + программирование + язык + руководство% 22 + & hl = de & sig = RxlDlRBWUvNAzsAFzqOcftrYI5E # v = onepage & q & f = false

Итак, вы можете реализовать все свои поведения как независимые классы, а затем дать каждой реализации зомби свое собственное сочетание поведения посредством реализации и композиции ..

Надеюсь, что это имеет смысл и поможет ...

3
ответ дан 28 November 2019 в 21:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: