it-roy-ru.com

Когда мне нужно использовать интерфейсы вместо абстрактных классов?

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

Давайте подумаем о следующем:

public abstract class Vehicle {
   abstract float getSpeed();
}

а также :

public interface IVehicle {
  float getSpeed();
}

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

В чем причина использования интерфейсов?

Спасибо!

Правка: Я нашел ссылку Nice об этом в другой теме: http://www.thecoldsun.com/en/content/01-2009/abstract-classes-and-interfaces

81
augmentie123

Из Java Как программировать об абстрактных классах:

Потому что они используются только как суперклассы в иерархиях наследования, мы называем их абстрактными суперклассами. Эти классы не могут быть используется для создания объектов, потому что абстрактные классы являются неполными. Подклассы должны объявить «недостающие части» стать «конкретными» классами из которого вы можете создавать экземпляры объектов. В противном случае эти подклассы тоже будет абстрактно.

Чтобы ответить на ваш вопрос «В чем причина использования интерфейсов?»:

Цель abstract класса - предоставить соответствующий суперкласс от которого другие классы могут наследовать и таким образом иметь общий дизайн.

В отличие от интерфейса:

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

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

91
kgdesouz

Из учебники Oracle :

В отличие от интерфейсов, классы abstract могут содержать поля, которые не являютсяstatic и final, и они могут содержать реализованные методы. Такие абстрактные классы похожи на интерфейсы, за исключением того, что они обеспечивают частичную реализацию, оставляя ее подклассам для завершения реализации. Если абстрактный класс содержит только объявления абстрактных методов, он должен быть объявлен как интерфейс.

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

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

15
Konstantin Yovkov

Многие случаи могут быть реализованы в обоих типах классов.

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

interface USB {
    public function sendPower(); //charge iphone for example
    public function sendData(); //iTunes
    public function recieveData();
}

Используйте абстрактные классы, когда есть несколько способов реализовать объект.

abstract class MobilePhone {
    public function isIphone();

    public function charge() {
        //get some power, all phones need that
    }
}

class iPhone extends MobilePhone {
    public function isIphone() { return true; }
}
8
DanFromGermany

Вы могли бы рассмотреть возможность использования интерфейса поверх абстрактной реализации несколько раз.

  • Когда доступная абстрактная реализация не делает то, что вы хотите, и вы хотите создать свою собственную
  • когда у вас есть существующий класс (который расширяется от другого класса), и вы хотите реализовать функциональность интерфейса

Вообще говоря, интерфейсы были введены для преодоления отсутствия множественного наследования, среди прочего 

7
MadProgrammer

Благодаря поддержке методов по умолчанию в интерфейсе с момента запуска Java 8, разрыв между классами interface и abstract уменьшился, но все же они имеют существенные различия.

  1. Переменные в интерфейсе: public static final. Но абстрактный класс может иметь другие типы переменных, такие как private, protected и т.д.

  2. Методы в интерфейсе: public или public static, но методы в абстрактном классе также могут быть private и protected

  3. Используйте abstract class, чтобы установить связь между взаимосвязанными объектами. Используйте interface, чтобы установить связь между несвязанными классами.

Посмотрите на эту article специальные свойства interface в Java 8. Статический модификатор для методов по умолчанию в интерфейсе вызывает ошибку времени компиляции в производной ошибке, если вы хотите использовать @override.

В этой статье объясняется, почему в Java 8 были введены методы по умолчанию: Для улучшения API коллекций в Java 8 для поддержки лямбда-выражений.

Взгляните на Oracle документацию, чтобы лучше понять различия.

Посмотрите на эти связанные вопросы SE с примером кода, чтобы понять вещи лучше: 

Как я должен был объяснить разницу между интерфейсом и абстрактным классом?

3
Ravindra babu

Из Учебные руководства Java ™ - Абстрактные классы по сравнению с интерфейсами

Что вы должны использовать, абстрактные классы или интерфейсы?

  • Рассмотрите возможность использования абстрактных классов, если любое из этих утверждений применимо к вашей ситуации:
    • Вы хотите поделиться кодом между несколькими тесно связанными классами.
    • Вы ожидаете, что классы, которые расширяют ваш абстрактный класс, имеют много общих методов или полей или требуют модификаторов доступа, отличных от public (например, protected и private).
    • Вы хотите объявить нестатические или не финальные поля. Это позволяет вам определять методы, которые могут обращаться и изменять состояние объекта, к которому они принадлежат.
  • Рассмотрите возможность использования интерфейсов, если любое из этих утверждений применимо к вашей ситуации:
    • Вы ожидаете, что несвязанные классы будут реализовывать ваш интерфейс. Например, интерфейсы Comparable и Cloneable реализованы многими несвязанными классами.
    • Вы хотите указать поведение определенного типа данных, но не беспокоитесь о том, кто реализует его поведение.
    • Вы хотите воспользоваться множественным наследованием типа.

Примером абстрактного класса в JDK является AbstractMap, который является частью Collections Framework. Его подклассы (которые включают HashMap, TreeMap и ConcurrentHashMap) совместно используют много методов (включая get, put, isEmpty, containsKey и containsValue), которые AbstractMap определяет.

3
Akash5288

Учитывая Java:

Интерфейсы:

  • Являются фундаментальной OOP абстракцией.
  • Часто (но не всегда) будет давать более четкий код, чем абстрактные классы.
  • Может быть реализовано несколькими конкретными классами для соответствия различным ситуациям.
  • Может напрямую реализовывать сценарии, требующие множественного наследования.
  • Может быть легко смоделирован для целей тестирования.
  • Полезны для прокси JDK (см. Java.lang.reflect.Proxy).

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

1
Arthur Dent

Используйте abstract class, когда вы хотите определить template для группы подклассов, и у вас есть по крайней мере некоторый код реализации, который могут использовать подклассы.

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

вы расширить абстрактный класс

вы реализовать интерфейс :)

в интерфейсе все поля автоматически publicstaticfinal и все методы являются public тогда как абстрактный класс позволяет вам немного гибкости здесь.

1
user2768308

Это прямая выдержка из превосходной книги Брюса Экеля « Thinking in Java ».

[..] Стоит ли использовать interface или abstract класс

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

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

1
fortytwo

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

Интерфейс : Он определяет только протокол, которому должен следовать весь подкласс.

0
Ravi Soni

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

Вы не можете расширить два класса, но вы можете реализовать несколько интерфейсов.

0
kavi temre

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

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

0
Will Jamieson

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

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

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

0
sridhar

интерфейс в основном используется, когда две стороны работают вместе, и одна сторона хочет что-то скрыть от другой (или хочет показать только часть своего класса). Чем мы используем интерфейс, например . в jdbc Поставщики jdbc предоставляют нам некоторые интерфейсы bcoz они хотят спрятать все от нас.

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

0
praveen tyagi

Ответ на этот вопрос очень прост: все, что мы можем сделать с интерфейсом, можно сделать с абстрактным классом «Согласен» ... поэтому, когда используются интерфейсы, ответ заключается в ограничении множественного наследования в C #. Когда у вас есть только контракты (тезисы) для объявления и вы хотите, чтобы ваши подклассы реализовывали это, используйте интерфейсы, потому что если вы используете абстрактный класс в этом случае, вы не можете наследовать от еще одного класса, и вы застряли, если хотите наследовать от одного. больше класса, но вы можете реализовать как можно больше интерфейсов.

0
Dinesh

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

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

0
HM Nayem

Interface и Abstract Class - это два разных способа достижения абстракции на OOP языках.

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

Абстрактный класс предоставляет 0 to 100% абстракцию, то есть он может иметь или не иметь абстрактные методы.

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

Мы можем использовать Abstract Class, когда реализатор Abstract Class может предоставить некоторые общие функциональные возможности, и клиенту будет предоставлена ​​возможность реализовать то, что ему действительно нужно. 

0
Raghu