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

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

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

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

и:

public interface IVehicle {
  float getSpeed();
}

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

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

Спасибо!

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

Ответ 1

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

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

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

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

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

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

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

Ответ 2

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

Рассмотрим использование абстрактных классов, если какое-либо из этих утверждений относится к вашей ситуации:

Вы хотите поделиться кодом между несколькими близкими классами.

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

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

Рассмотрите возможность использования интерфейсов, если какое-либо из этих утверждений относится к вашей ситуации:

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

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

Вы хотите использовать множественное наследование типа.

Ответ 3

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

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

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

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

Ответ 4

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

Интерфейсы полезны, если вы хотите определить класс, который должен иметь как минимум базовые функции. Как настоящий интерфейс, например 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; }
}

Ответ 5

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

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

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

Ответ 6

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

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

  • Методы в интерфейсе public или public static, но методы в абстрактном классе могут быть private и защищены strong > слишком

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

Посмотрите на статью для специальных свойств интерфейса в java 8. static modifier для методов по умолчанию в интерфейсе вызывает ошибку времени компиляции в если вы хотите использовать @override.

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

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

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

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

Ответ 7

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

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

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

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

Ответ 8

Рассмотрение Java:

Интерфейсы:

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

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

Ответ 9

Используйте класс abstract, если вы хотите определить шаблон для группы подклассов, и у вас есть хотя бы некоторый код реализации, вызывающий подклассы использовать.

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

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

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

в интерфейсе все поля автоматически public static final, а все методы - public тогда как абстрактный класс позволяет вам немного гибко.

Ответ 10

Это прямая выдержка из превосходной книги "" Мышление в Java" от Брюса Эккеля.

[..] Следует ли использовать интерфейс или абстрактный класс?

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

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

Ответ 11

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

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

Ответ 12

Интерфейс

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

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

Ответ 13

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

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

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

Ответ 14

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

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

Ответ 15

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

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

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

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

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

Ответ 16

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

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

Ответ 17

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

Ответ 18

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

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

Ответ 19

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

Абстракция основана на хорошем соотношении "is-a". Это означает, что вы сказали бы, что автомобиль - это Honda, а Honda - автомобиль. Использование абстракции в классе означает, что вы также можете использовать абстрактные методы. Для этого требуется, чтобы какой-либо подкласс расширялся от него, чтобы получить абстрактные методы и переопределить их. Используя приведенный ниже пример, мы можем создать абстрактный метод howToStart(); метод, который потребует, чтобы каждый класс реализовал его.

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

public abstract class Car{
    private String make;
    private String model

    protected Car() { }  // Default constructor

    protect Car(String make, String model){
        //Assign values to 
    }

    public abstract void howToStart();
}

Тогда с классом Honda мы бы получили:

public class Honda extends implements Engine {

    public Honda() { }  // Default constructor

    public Honda(String make, String model){
        //Assign values
    }

    @Override
    public static void howToStart(){
        // Code on how to start
    }

}

Интерфейсы основаны на отношении "has-a". Это означает, что вы можете сказать, что у автомобиля есть двигатель, но двигатель не автомобиль. В приведенном выше примере Honda имеет implements Engine.

Для интерфейса двигателя мы можем создать:

public interface Engine {
    public void startup();
}

Интерфейс предоставит много-один экземпляр. Поэтому мы могли бы применить интерфейс Engine к любому типу автомобиля. Мы также можем распространить его на другой объект. Так же, как если бы мы собирались сделать класс лодки и иметь подклассы типов лодок, мы могли бы расширить движок и иметь подклассы лодки, требующие метода startup();. Интерфейсы хороши для создания фреймворка для различных классов, которые имеют некоторое сходство. Мы также можем реализовать несколько экземпляров в одном классе, например:

public class Honda extends implements Engine, Transmission, List<Parts>

Надеюсь, это поможет.

Ответ 20

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