Продолжение назначения интерфейсов - PullRequest
5 голосов
/ 29 октября 2010

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

Но если все, что у вас есть в интерфейсе, это:

 public interface animal{
  void eat(object food);
}

, и у него нет реализации как таковой, то тот, кто использует ваш интерфейс, должен написатьэто каждый раз с нуля.

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

Любая помощь, чтобы разобраться в этом, ценится, потому что я знаю, что это действительно важно.

Ответы [ 13 ]

20 голосов
/ 29 октября 2010

Интерфейсы являются единственным способом создания множественного наследования в Java.

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

Но теперь допустим, что у вас есть MathProblem класс. И вы хотите иметь определенные классы, которые могут решить эту проблему, передав ее в метод solve(MathProblem problem). И вы знаете, что Human, но также Computer может решить математическую задачу. Таким образом, они оба должны быть в состоянии решить эту проблему. Возможно, вы сможете заставить Компьютер расширить некоторый класс MathSolver, который имеет метод, но Человек уже расширяет Animal и не может расширять что-либо еще. Таким образом, лучший способ - сделать MathSolver интерфейсом и иметь как Human, Computer, так и любые другие классы, которые должны решать проблемы, реализующие это.

Также обратите внимание, что Human и Computer могут решить проблемы совершенно по-разному, поскольку их такие разные объекты. Вот для чего лучше всего использовать интерфейсы. Определение определенных способностей, которые пересекают несколько иерархий наследования и могут иметь очень разные реализации, но все они могут быть переданы методу, который принимает любую из них. Подумайте об интерфейсе Comparable; это не то, что имеет определенный класс объектов, все виды вещей можно сравнивать, и, как правило, совершенно по-разному. Но вы всегда можете вызвать сортировку для List из Comparable объектов, поскольку вы знаете, что они имеют определенный порядок, независимо от того, являются ли они Numbers, Animals, Computers или чем-то еще (до тех пор, пока реализовать Comparable и определить их порядок).

4 голосов
/ 29 октября 2010

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

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

3 голосов
/ 29 октября 2010

Вы путаете интерфейсы и наследование.Это разные понятия и могут дополнять друг друга.Если все методы eat немного отличаются, вы можете создать базовый класс, который будет содержать общий код и вызываться из подклассов через переопределенные методы, которые добавляют разные части.Базовый класс все еще может реализовывать интерфейс.Надеюсь, это понятно.

2 голосов
/ 29 октября 2010

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

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

HTH.Томас

1 голос
/ 19 мая 2016

Обобщение

Используя JAVA Interface, мы можем добиться обобщения по подклассам. Обобщение означает здесь подклассы, имеющие одинаковое поведение, реализованное по-разному.

Стандартизация

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

100% Абстракция

Тело интерфейса обеспечивает 100% абстракцию, поэтому подкласс не должен пропускать реализацию абстрактного метода. Это невозможно, если мы используем абстрактные классы.

Разъединение (слабая связь)

При разработке приложения код, который взаимодействует с конечными пользователями, может быть свободно связан с кодом, выполняющимся на сервере [B L C], с помощью интерфейсов.

Множественное наследование

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

1 голос
/ 08 сентября 2012

А старые темы, я знаю.Но я только что прочитал «Интерфейсы - единственный способ создать множественное наследование в Java».Это очень неправильно, потому что делегирование (или «составление», как сказал Карл) - единственный способ получить множественное наследование (помните: «делегирование - это наследование», ну, почти).

Вам нужны только интерфейсы, чтобы сообщитьразработчик "эй, не забудьте передать тот или иной класс"!Интерфейсы нужны только как напоминание для правильного делегирования (или вообще: для реализации), но они не могут наследовать какой-либо код.С несколькими интерфейсами наследования вообще не понадобится.

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

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

1 голос
/ 29 октября 2010

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

Например, один из способовмы часто используем интерфейсы на нашем бизнес-уровне / уровне доступа к данным.

Поскольку наша сборка бизнес-уровня (BL) будет напрямую взаимодействовать со сборкой уровня доступа к данным (DAL), DAL не может напрямую взаимодействовать скипаЧто происходит, если DAL хочет использовать объекты, а не отдельные поля?Вы должны будете определить свои собственные объекты DAL и гидрировать их только что полученным вводом.По сути, гораздо больше работы, больше потребляемых ресурсов и несколько объектов, представляющих одни и те же данные, что создает кошмар обслуживания.

Но если вы определяете интерфейсы в DAL, вы можете сказать потребителям DAL, чтоэто ожидает.Затем вы можете реализовать эти интерфейсы в BL и передавать экземпляры интерфейсов вместо объектов BL.

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

[Редактировать] Если у вас много объектов, которые делают схожие вещи, комбинация интерфейса и базового класса с переопределенными / виртуальными методами может оказаться более полезной, чем просто интерфейс.

1 голос
/ 29 октября 2010

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

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

class Herbivore implements Animal {
  public void eat(Object food) {
   ...
  }
}

class Cow extends Herbivore..
class Horse extends Herbivore..

и вы можете переопределить eat, используя super.eat() и изменяя только небольшую часть ..

Вы должны ожидать повторного использования кода и инкапсуляции компонентов одновременно ... тогда, если ваш интерфейс действительно не характеризует сам класс, а является только его компонентом, вы можете перейти по составу, как это предложил Карл Манастер. *

1 голос
/ 29 октября 2010

Правильно, вам нужно реализовывать его всегда, но вы можете реализовывать его каждый раз по-разному, и любой класс, который вызывает его, не должен беспокоиться о том, как он реализован.

Например, если у вас есть объект Zoo с кучей животных (новый Tiger (), Lion (), Bear ()), то ваш зоопарк может сделать для каждого животного a в некоторой коллекции a.eat () и его буду работать. Зоопарку все равно, что есть три разных типа животных, которые едят совершенно по-разному.

0 голосов
/ 26 апреля 2015

Одной из основных причин является то, что вы можете создать объект, используя ссылку на интерфейс, аналогично абстрактному методу. Когда вы делаете это, каждый объект, который реализует интерфейс, может быть назначен ему. Например, если Dog и Car используют Washable, вы можете выполнить:

Моющиеся wD = новая собака ();

Моющиеся wC = новый автомобиль ();

Если Washable имеет публичный абстрактный метод wash (), то вы можете сделать это:

wD.wash ();

wC.wash ();

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

Более подробное объяснение см. Здесь: http://www.artima.com/objectsandjava/webuscript/PolymorphismInterfaces1.html

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