Подтвердить что ты не робот

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

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

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

Ответ 3

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

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

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

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

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

http://books.google.com/books?id=ZZOiqZQIbRMC&pg=RA1-PA71&lpg=RA1-PA71&dq=%22Bloch%22+%22Effective+java:+programming+language+guide%22+&hl=de&sig=RxlDlRBWUvNAzsAFzqOcftrYI5E#v=onepage&q&f=false

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

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

Ответ 4

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

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

Ответ 5

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

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

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

Ответ 6

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

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

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

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

не уверен, что вы подразумеваете под этим.

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

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

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

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

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

возможно, это больше аргумента для интерфейса.

см

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

Ответ 7

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

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

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

Ответ 8

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

Скажите, что у вас есть метод Move, который заставляет ходячих зомби ходить, бежать в бегах, и т.д. Однако, если вы хотите "Переместить", чтобы какой-нибудь зомби делал что-то общее, тогда интерфейс заставит вас дублировать кода, поскольку вы не можете поместить тело в интерфейс.

Ответ 9

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

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