Будет ли это правильным местом для использования ключевого слова Java "интерфейс"? - PullRequest
3 голосов
/ 10 апреля 2009

Я довольно новичок в Java. Просто прочитав некоторую информацию о поиске пути, я прочитал об использовании пустого класса в качестве "interface" для неизвестного типа объекта.

Я занимаюсь разработкой игры на Java на тему больницы. Пока что пользователь может построить приемную и кабинет врача общей практики. Это два типа объектов, один из которых Building, а другой - ReceptionDesk. (В моей структуре классов.)

Моя структура классов такова:

GridObject-->Building
GridObject-->Item-->usableItem-->ReceptionDesk.

Проблема возникает, когда используемый предмет можно повернуть, а здание - нет. Событие щелчка мыши находится в сетке, поэтому вызывает тот же метод. Офис ГП - Building, а стойка регистрации - ReceptionDesk. Только у ReceptionDesk есть метод rotate. При щелчке правой кнопкой мыши по сетке, если в режиме здания, я должен использовать это выражение «если»:

if (currentBuilding.getClass.equals(ReceptionDesk.getClass)

Затем я должен создать новый ReceptionDesk, использовать метод rotate и поставить стойка регистрации обратно в currentBuilding GridObject.

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

Я не планировал изучать это, пока не увидел, насколько быстрыми и полезными были ответы на этом сайте! :)

Заранее спасибо.

Rel

Ответы [ 3 ]

7 голосов
/ 10 апреля 2009

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

Если вы опишете еще несколько объектов, которые, по вашему мнению, вам нужны, у людей здесь будет мнение о том, как вы должны их расположить. Но из того, что вы предоставили, вы можете захотеть создать интерфейс «Building», который определяет некоторые общие методы. Вам также может потребоваться интерфейс «UsableItem» или что-то более общее. Больница может быть классом, который реализует строительство. ReceptionDesk может реализовать UsableItem. В здании может быть сетка UsableItem.

Если rotate () был общим методом для всей мебели, которая фактически выполнила некоторую работу, вы можете рассмотреть возможность создания класса AbstractUsableItem, который был бы абстрактным классом, реализующим UsableItemand, предоставляющим метод rotate (). Если бы rotate был разным в каждом реализующем классе, у вас был бы этот метод в интерфейсе, но каждый класс, как ReceptionDesk, делал бы свое дело с методом rotate (). Ваш код будет делать что-то вроде:

UsableItem desk = new ReceptionDesk();
desk.rotate()

В вашем примере, если ваш щелчок мыши по экрану повернул объект под ним, и вам действительно нужно было проверить, можно ли повернуть объект, прежде чем делать что-то подобное, вы должны сделать

if (clickedObject instanceOf UsableItem) {
  ((UsableItem) clickedObject).rotate();
}

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

3 голосов
/ 10 апреля 2009

Вы можете подумать о том, чтобы двигаться в совершенно ином направлении, и чтобы объекты сами решали, какое действие предпринять. Например, интерфейс GridObject может определять объявления функций для handleRightClick (), handleLeftClick () и т. Д. В этом случае вы можете сказать, что «любой класс, который вызывает себя, GridObject должен указать, что происходит, когда они щелкаются правой кнопкой мыши ».

Таким образом, в классе Building вы можете реализовать handleRightClick, чтобы ничего не делать (или возвращать ошибку). В классе ReceptionDesk вы бы реализовали handleRightClick для поворота стола.

Ваш фрагмент кода станет:

currentBuilding.handleRightClick(... any necessary parameters ...);
1 голос
/ 10 апреля 2009

Вы правы, что беспокоитесь. Хорошее практическое правило для объектно-ориентированного проектирования заключается в том, что всякий раз, когда вы используете такую ​​конструкцию, как if(x instanceof Y) или if(x.getClass().equals(Y.class)), вам следует задуматься о перемещении методов вверх или вниз или извлечении новых методов.

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

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

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