В чем разница между интерфейсом и абстрактным классом?
======================================================

В чем же разница между интерфейсом и абстрактным классом?

 

 Интерфейсы
-----------

  Интерфейс - это **контракт**: человек, пишущий интерфейс, говорит: "Эй, я принимаю вещи, смотрящие таким образом", а человек, использующий интерфейс, говорит "ОК, класс, который я пишу, выглядит так".

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

  Например (псевдокод):

 
```
// I say all motor vehicles should look like this:
interface MotorVehicle
{
    void run();

    int getFuel();
}

// My team mate complies and writes vehicle looking that way
class Car implements MotorVehicle
{

    int fuel;

    void run()
    {
        print("Wrroooooooom");
    }

    int getFuel()
    {
        return this.fuel;
    }
}

```
  Реализация интерфейса потребляет очень небольшой процессор, потому что это не класс, просто куча имен, и, следовательно, нет никакого дорогостоящего поиска. Это здорово, когда это имеет значение, например, во встроенных устройствах.

 

---

 Абстрактные классы
-------------------

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

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

  Например:

 
```
// I say all motor vehicles should look like this:
abstract class MotorVehicle
{

    int fuel;

    // They ALL have fuel, so lets implement this for everybody.
    int getFuel()
    {
         return this.fuel;
    }

    // That can be very different, force them to provide their
    // own implementation.
    abstract void run();
}

// My teammate complies and writes vehicle looking that way
class Car extends MotorVehicle
{
    void run()
    {
        print("Wrroooooooom");
    }
}

```
 

---

 Реализация
-----------

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

  В Java это правило строго соблюдается, тогда как в PHP интерфейсы являются абстрактными классами без объявленного метода.

  В Python абстрактные классы - это скорее программный трюк, который вы можете получить из модуля ABC и на самом деле используете метаклассы и, следовательно, классы. И интерфейсы больше связаны с утиным набором текста на этом языке, и это сочетание между условностями и специальными методами, которые называют дескрипторы (методы \_\_method\_\_).

  Как обычно с программированием, на другом языке есть теория, практика и практика :-)

 

Основные технические различия между [абстрактным классом](http://us2.php.net/abstract) и [interface](http://us2.php.net/interface):

* Абстрактные классы могут иметь константы, члены, заглушки методов (методы без тела) и определенные методы, тогда как интерфейсы могут содержать только константы и методы.
* Методы и члены абстрактного класса могут быть определены с любой видимостью, тогда как все методы интерфейса должны быть определены как `public` (по умолчанию они определены общедоступными).
* При наследовании абстрактного класса конкретный дочерний класс должен определять абстрактные методы, тогда как абстрактный класс может расширять другой абстрактный класс, а абстрактные методы из родительского класса не должны определяться.
* Аналогично, интерфейс, расширяющий другой интерфейс, не отвечает за реализацию методов из родительского интерфейса. Это связано с тем, что интерфейсы не могут определить какую-либо реализацию.
* Детский класс может расширять только один класс (абстрактный или конкретный), тогда как интерфейс может расширяться или класс может реализовать несколько других интерфейсов.
* Детский класс может определять абстрактные методы с той же или менее ограничительной видимостью, тогда как класс, реализующий интерфейс, должен определять методы с одинаковой видимостью (public).

 

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

  [![enter image description here]()](/img/20156b5abda89c6cb531680a00c47eff.png) Взято из:

  <http://www.dotnetbull.com/2011/11/difference-between-abstract-class-and.html>

  <http://www.dotnetbull.com/2011/11/what-is-abstract-class-in-c-net.html> [http://www.dotnetbull.com/2011/11/what-is-interface-in -с-net.html](http://www.dotnetbull.com/2011/11/what-is-interface-in-c-net.html)

 

Объяснение можно найти здесь: <http://www.developer.com/lang/php/article.php/3604111/PHP-5-OOP-Interfaces-Abstract-Classes-and-the-Adapter-Pattern.htm>

>  Абстрактный класс - это класс, который только частично программист. Он может содержать один или несколько абстрактные методы. Абстрактный метод просто определение функции, которое служит для указания программисту, что метод должен быть реализован у ребенка класс.
> 
>  Интерфейс подобен абстрактному класс; действительно, интерфейсы занимают такое же пространство имен как классы и абстрактные классы. По этой причине вы не можете определить интерфейс с тем же именем как класс. Интерфейс полностью абстрактный класс; ни один из его методов реализованы и вместо класса суб-классификация из него, говорят реализовать этот интерфейс.
> 
> 
> 

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

 

Некоторые важные отличия:

В виде таблицы:

 ![Difference]()

Как [указанный Джо из javapapers](http://javapapers.com/core-java/abstract-and-interface-core-java-2/difference-between-a-java-interface-and-a-java-abstract-class/):

>  1. Разница в методах интерфейса Java неявно абстрактна и не может иметь реализаций. Абстрактный класс Java может имеют методы экземпляра, которые реализуют поведение по умолчанию.
> 
>  2. Переменные, объявленные в интерфейсе Java, по умолчанию являются окончательными. Абстрактный класс может содержать не конечные переменные.
> 
>  3. Члены интерфейса Java по умолчанию являются общедоступными. Абстрактный класс Java может иметь обычные вкусы членов класса, таких как частные, защищены и т.д.
> 
>  Интерфейс 4.Java должен быть реализован с использованием ключевого слова "инструменты"; Класс абстрактных Java должен быть расширен с использованием ключевого слова "extends".
> 
>  Интерфейс 5.An может распространять только другой интерфейс Java, абстрактный класс может расширить другой класс Java и реализовать несколько Java интерфейсы.
> 
>  6. Java-класс может реализовывать несколько интерфейсов, но может расширять только один абстрактный класс.
> 
>  7. Поверхность абсолютно абстрактна и не может быть создана; Явный абстрактный класс также не может быть создан, но может быть вызван, если main() существует.
> 
>  8. По сравнению с абстрактными классами Java, java-интерфейсы медленны, так как для этого требуется дополнительная косвенность.
> 
> 
> 

 

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

Проще говоря, я хотел бы сказать:

интерфейс: для реализации контракта несколькими несвязанными объектами

абстрактный класс: реализовать то же или другое поведение среди нескольких связанных объектов

Из документации Oracle 

Рассмотрим использование абстрактных классов, если:

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

Рассмотрим использование интерфейсов, если:

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

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

Если вы ищете `Java` как язык программирования, добавьте еще несколько обновлений:

Java 8 в некоторой степени сократила разрыв между классами `interface` и `abstract`, предоставив функцию метода `default`. Интерфейс не имеет реализации для метода, теперь недействителен.

Подробнее см. в этой документации [страница](https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html).

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

 [Как я должен объяснить разницу между интерфейсом и абстрактным классом?](/questions/2087/how-should-i-have-explained-the-difference-between-an-interface-and-an-abstract-class/23775#23775)

 

Главное, что:

* **Аннотация ориентировано на объекты**. Он предлагает базовые данные, которые должен иметь объект и/или функции, которые он должен выполнять. Он связан с основными характеристиками объекта: чем он обладает и что он может сделать. Следовательно, объекты, которые наследуются от одного и того же абстрактного класса, разделяют основные характеристики (обобщение).
* **Интерфейс ориентирован на функциональность**. Он определяет функциональные возможности объекта. Независимо от того, какой объект он имеет, до тех пор, пока он может выполнять эти функции, которые определены в интерфейсе, это прекрасно. Он игнорирует все остальное. Объект/класс может содержать несколько (групп) функциональных возможностей; поэтому класс может реализовывать несколько интерфейсов.

 

 Я строю здание из 300 этажей

  **Интерфейс** здания план

 * Например, Servlet (I)

 Здание построено до 200 этажей - частично completed--- **реферат**

 * Частичная реализация, например, общий и HTTP-сервлет

 Строительство зданий completed- **бетон**

 * Полная реализация, например, собственный сервлет

 Интерфейс

 * Мы ничего не знаем о реализации, просто требования. Мы можем пойти на интерфейс.
* Каждый метод является общедоступным и абстрактным по умолчанию
* Это 100% чистый абстрактный класс
* Если мы объявляем общественность, мы не можем объявлять частные и защищенные
* Если мы объявим абстрактное, мы не сможем объявить окончательный, статический, синхронизированный, strictfp и native
* Каждый интерфейс имеет открытый, статический и конечный
* Сериализация и переходный процесс неприменимы, поскольку мы не можем создать экземпляр для интерфейса
* Энергонезависимый, поскольку он является окончательным
* Каждая переменная является статической
* Когда мы объявляем переменную внутри интерфейса, нам нужно инициализировать переменные при объявлении
* Экземпляр и статический блок не разрешены

 Аннотация

 * Частичная реализация
* Он имеет абстрактный метод. Кроме того, он использует бетон
* Без ограничений для модификаторов метода абстрактного класса
* Никаких ограничений для модификаторов переменных абстрактного класса
* Мы не можем объявлять другие модификаторы, кроме абстрактных
* Никаких ограничений для инициализации переменных

 Снято с сайта DurgaJobs

 

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

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

 

Вернемся к этому вопросу еще раз:

Первое, что вам известно, это то, что результаты 1/1 и 1 * 1 совпадают, но это не означает, что умножение и деление одинаковы. Очевидно, что у них хорошие отношения, но вы оба разные.

Я укажу основные отличия, а остальные уже объяснены:

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

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

 

Это довольно просто.

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

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

Абстрактный класс позволяет вам как объявлять (используя абстрактные методы), так и определять (используя полные реализации метода) поведение, которое вы хотите, чтобы класс имел.

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

Последнее,

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

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

Интерфейсы, с другой стороны, вы могли бы просто выполнить: интерфейс C реализует A, B

Таким образом, Java поддерживает множественное наследование только в "объявленном поведении", т.е. интерфейсах, и только одинарном наследовании с определенным поведением.. если вы не делаете раунд о том, как я описал...

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

 

Абстрактный класс без какой-либо реализации просто выглядит как интерфейс; однако есть много различий, чем сходство между абстрактным классом и интерфейсом. Позвольте объяснить обе концепции и сравнить их сходства и различия.

  **Что такое абстрактный класс?**

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

  **Что такое интерфейс?**

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

  **Оба вместе**

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

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

---

Есть некоторые сходства и различия между интерфейсом и абстрактным классом.
[![введите описание изображения здесь]()](/img/74c8f9325d240d33cdc2bccd5aa64ff9.jpg)

 

Сравнение интерфейса с абстрактным классом неверно. Вместо этого должно быть два других сравнения: 1)  **интерфейс против класса** и 2)  **абстрактный и окончательный класс**.

 Интерфейс vs Класс
===================

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

```
interface Package {
  String address();
}

```

  **Класс** - это группа объектов, которые подчиняются контракту. Например, я ящик из группы "Ящик", и я подчиняюсь контракту, требуемому Почтальон. В то же время я подчиняюсь другим контрактам:

```
class Box implements Package, Property {
  @Override
  String address() {
    return "5th Street, New York, NY";
  }
  @Override
  Human owner() {
    // this method is part of another contract
  }
}

```

 Аннотация против финала
========================

  **Абстрактный класс** - это группа неполных объектов. Они не могут использоваться, потому что они пропускают некоторые части. Например, я абстрактная коробка с поддержкой GPS - я знаю, как проверить свою позицию на карте:

```
abstract class GpsBox implements Package {
  @Override
  public abstract String address();
  protected Coordinates whereAmI() {
    // connect to GPS and return my current position
  }
}

```

Этот класс, если он унаследован/расширен другим классом, может быть очень полезным. Но само по себе - бесполезно, поскольку у него нет объектов. Абстрактными классами могут быть элементы из конечных классов.

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

```
final class DirectBox implements Package {
  private final String to;
  public DirectBox(String addr) {
    this.to = addr;
  }
  @Override
  public String address() {
    return this.to;
  }
}

```

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

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

 

Объяснение можно найти в [Интерфейс VS Abstract Class в PHP](http://widwebway.com/en/blog/?p=30).

###  Заключение

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

 

Разница лишь в том, что один может участвовать в множественном наследовании, а другой - нет.

Определение интерфейса со временем изменилось. Как вы думаете, интерфейс имеет только объявления методов и является просто контрактами? А как насчет статических конечных переменных и определений по умолчанию после Java 8?

Интерфейсы были введены в Java из-за [проблемы алмазов](https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem) с множественным наследованием и того, что они на самом деле намерены делать.

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

См. [Почему Java допускает статические конечные переменные в интерфейсах, если они предназначены только для контрактов?](http://www.quora.com/Why-does-Java-allow-static-final-variables-in-interfaces-when-they-are-only-intended-to-be-contracts).



  **В чем разница между интерфейсом и абстрактным классом?**

>    **Абстрактный класс**
> 
> 
> 

* Для абстрактного класса метод должен быть объявлен как абстрактный. Абстрактные
метод не имеет реализации.
* Абстрактные методы могут быть объявлены с помощью модификаторов доступа, таких как public,
внутренние, защищенные и т.д. При реализации этих методов в подклассе вы должны определить их с той же (или менее ограниченной) видимостью.
* Абстрактные классы могут содержать переменные и конкретные методы.
* Класс может наследовать только один абстрактный класс
* Множественное наследование невозможно для абстрактного класса.

>    **Интерфейс**
> 
> 
> 

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

 

Короче говоря, различия заключаются в следующем:

Синтаксические различия между  **Интерфейсом** и  **Абстрактным классом**:

* Методы и члены абстрактного класса могут иметь любую видимость. Все методы  **интерфейса** должны быть  **общедоступными**.//Не верен с Java 9 больше
* Конкретный дочерний класс класса  **Аннотация** должен определить все абстрактные методы.  **Абстрактный** дочерний класс может иметь абстрактные методы. Интерфейс, расширяющий другой интерфейс, не должен обеспечивать реализацию по умолчанию для методов, унаследованных от родительского интерфейса.
* Детский класс может расширять только один класс.  **интерфейс** может расширять несколько интерфейсов. Класс может реализовывать несколько интерфейсов.
* Детский класс может определять абстрактные методы с той же или менее ограничительной видимостью, тогда как класс, реализующий  **интерфейс**, должен определять все методы интерфейса как общедоступные.
* **Абстрактные классы** могут иметь конструкторы, но не  **интерфейсы**.
* Интерфейсы Java 9 имеют частные статические методы.

В интерфейсах теперь:

 `public static` - поддерживается   
`public abstract` - поддерживается   
`public default` - поддерживается   
`private static` - поддерживается   
`private abstract` - ошибка компиляции   
`private default` - ошибка компиляции   
`private` - поддерживается

 

Интерфейс: Поверните (поверните налево, поверните направо.)

Абстрактный класс: Колесо.

Класс: Рулевое колесо, полученное из колеса, предоставляет интерфейс Turn

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

 

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

  Следующие примеры демонстрируют это.

  Абстрактный класс в Java:

 
```
abstract class animals
{
    // They all love to eat. So let implement them for everybody
    void eat()
    {
        System.out.println("Eating...");
    }
    // The make different sounds. They will provide their own implementation.
    abstract void sound();
}

class dog extends animals
{
    void sound()
    {
        System.out.println("Woof Woof");
    }
}

class cat extends animals
{
    void sound()
    {
        System.out.println("Meoww");
    }
}

```
  Ниже приведена реализация интерфейса в Java:

 
```
interface Shape
{
    void display();
    double area();
}

class Rectangle implements Shape 
{
    int length, width;
    Rectangle(int length, int width)
    {
        this.length = length;
        this.width = width;
    }
    @Override
    public void display() 
    {
        System.out.println("****\n* *\n* *\n****"); 
    }
    @Override
    public double area() 
    {
        return (double)(length*width);
    }
} 

class Circle implements Shape 
{
    double pi = 3.14;
    int radius;
    Circle(int radius)
    {
        this.radius = radius;
    }
    @Override
    public void display() 
    {
        System.out.println("O"); // :P
    }
    @Override
    public double area() 
    { 
        return (double)((pi*radius*radius)/2);
    }
}

```
  Некоторые важные ключевые моменты в двух словах:

 1. Переменные, объявленные в интерфейсе Java, по умолчанию являются окончательными. Абстрактные классы могут иметь не конечные переменные.
2. Переменные, объявленные в интерфейсе Java, по умолчанию статичны. Абстрактные классы могут иметь нестатические переменные.
3. Участники интерфейса Java по умолчанию являются общедоступными. Абстрактный класс Java может иметь обычные вкусы членов класса, таких как частные, защищенные и т.д.

 

На самом деле не ответ на исходный вопрос, но как только вы получите ответ на разницу между ними, вы будете вводить в каждом случае дилемму:
[Когда использовать интерфейсы или абстрактные классы? Когда использовать оба?](/questions/2084/when-to-use-interfaces-or-abstract-classes-when-to-use-both)

Я ограничил знание ООП, но просмотр интерфейсов как эквивалента прилагательного в грамматике работал у меня до сих пор (исправьте меня, если этот метод фиктивный!). Например, имена интерфейсов похожи на атрибуты или возможности, которые вы можете дать классу, и класс может иметь много из них: ISerializable, ICountable, IList, ICacheable, IHappy,...

 

Наследование используется для двух целей:

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

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

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

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

 

Ключевые моменты:

* Абстрактный класс может иметь свойство, поля данных, методы (полный/
неполный) обе.
* Если метод или Свойства определяют в абстрактном ключевом слове, которое должно переопределяться в производном классе. (его работа как тесно связанная
функциональность)
* Если определить абстрактное ключевое слово для метода или свойств в абстрактном классе, вы не можете определить тело метода и получить/установить значение для
свойства, которые должны переопределяться в производном классе.
* Абстрактный класс не поддерживает множественное наследование.
* Абстрактный класс содержит конструкторы.
* Абстрактный класс может содержать модификаторы доступа для подмножеств, функций, свойств.
* Только полный член абстрактного класса может быть статическим.
* Интерфейс может наследовать только от другого интерфейса и не может наследовать от абстрактного класса, где абстрактный класс может наследовать от другого абстрактного класса или другого интерфейса.

Преимущество:

* Это своего рода контракт, который заставляет все подклассы выполнять одни и те же иерархии или стандарты.
* Если различные реализации имеют один и тот же вид и используют общее поведение или статус, тогда лучше использовать абстрактный класс.
* Если мы добавим новый метод в абстрактный класс, то у нас есть возможность обеспечить реализацию по умолчанию, и поэтому весь существующий код может работать правильно.
* Это позволяет быстро выполнить, чем интерфейс. (interface Требуется больше времени для поиска фактического метода в соответствующих классах.)
* Он может использоваться для жесткой и свободной связи.

найти подробности здесь...
<http://pradeepatkari.wordpress.com/2014/11/20/interface-and-abstract-class-in-c-oops/>

 

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

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

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

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

Подробнее читайте [разницу между абстрактным классом и интерфейсом](http://rangahc.blogspot.in/2014/06/difference-between-abstract-class-and-interface-in-CSharp.html)

 

Самый короткий способ подвести итог - это `interface`:

* Полностью абстрактно, кроме методов `default` и `static`; в то время как он имеет определения (сигнатуры методов + реализации) для методов `default` и `static`, у него есть только декларации (сигнатуры методов) для других методов.
* В соответствии с правилами laxer, чем классы (класс может реализовать несколько `interface` s, а `interface` может наследовать от нескольких `interface` s). Все переменные неявно постоянны, независимо от того, указан ли он как `public static final` или нет. Все члены неявно `public`, независимо от того, указаны они как таковые или нет.
* Обычно используется как гарантия того, что класс реализации будет иметь указанные функции и/или быть совместимым с любым другим классом, который реализует один и тот же интерфейс.

Между тем класс `abstract`:

* В любом месте от полностью абстрактного до полностью реализованного, с тенденцией иметь один или несколько методов `abstract`. Может содержать как декларации, так и определения, с объявлениями, отмеченными как `abstract`.
* Полноценный класс и подчиняется правилам, управляющим другими классами (может наследовать только один класс) при условии, что он не может быть создан (потому что нет гарантии, что он полностью реализован). Может иметь постоянные переменные-члены. Может реализовывать контроль доступа элемента, ограничивая его как `protected`, `private` или частный пакет (неуказанный).
* Обычно используется либо для обеспечения большей части реализации, которая может использоваться несколькими подклассами, либо для обеспечения такой же реализации, какой может предоставить программист.

Или, если мы хотим сварить все до одного предложения: `interface` - это класс реализации, но класс `abstract` - это подкласс.

 

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

 

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

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

 

  **Различия между абстрактным классом и интерфейсом от имени реальной реализации.**

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

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

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

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

  **Пример абстрактного класса:**

```
 public abstract class DesireCar
  {

 //It is an abstract method that defines the prototype.
     public abstract void Color();

  // It is a default implementation of a Wheel method as all the desire cars have the same no. of wheels.   
 // and hence no need to define this in all the sub classes in this way it saves the code duplicasy     

  public void Wheel() {          

               Console.WriteLine("Car has four wheel");
                }
           }

    **Here is the sub classes:**

     public class DesireCar1 : DesireCar
        {
            public override void Color()
            {
                Console.WriteLine("This is a red color Desire car");
            }
        }

        public class DesireCar2 : DesireCar
        {
            public override void Color()
            {
                Console.WriteLine("This is a red white Desire car");
            }
        }

```

  **Пример интерфейса:**

```
  public interface IShape
        {
          // Defines the prototype(template) 
            void Draw();
        }

  // All the sub classes follow the same template but implementation can be different.

    public class Circle : IShape
    {
        public void Draw()
        {
            Console.WriteLine("This is a Circle");
        }
    }

    public class Rectangle : IShape
    {
        public void Draw()
        {
            Console.WriteLine("This is a Rectangle");
        }
    }

```
 

Вы можете найти четкую разницу между  **интерфейсом** и  **абстрактным классом.**

  **Интерфейс**

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

  **Абстрактный класс**

* Абстрактный класс содержит абстрактные и не абстрактные методы.
* Не заставляет пользователей внедрять все методы при унаследовании
абстрактный класс.
* Содержит все виды переменных, включая примитивные и непримитивные
* Объявить использование абстрактного ключевого слова.
* Методы и члены абстрактного класса могут быть определены с помощью любых
видимость.
* Детский класс может расширять только один класс (абстрактный или конкретный).

 

Многие младшие разработчики ошибаются, думая о интерфейсах, абстрактных и конкретных классах как о незначительных вариациях одной и той же вещи и выбирают одну из них исключительно по техническим причинам: нужно ли мне многократное наследование? Нужно ли мне какое-то место для размещения общих методов? Нужно ли мне беспокоиться о чем-то отличном от конкретного класса? Это неправильно, и скрытые в этих вопросах основная проблема:  **"Я"** . Когда вы сами пишете код, вы редко думаете о других существующих или будущих разработчиках, работающих с вашим кодом или с вашим кодом.

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

 Резюме
-------

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

 Альтернативное резюме
----------------------

* Интерфейс предназначен для определения общедоступных API
* Абстрактный класс предназначен для внутреннего использования и для определения SPI

###  О важности скрытия деталей реализации

Конкретный класс действительно работает, очень определенным образом. Например, `ArrayList` использует непрерывную область памяти для хранения списка объектов в компактном виде, который предлагает быстрый случайный доступ, итерацию и изменения на месте, но ужасен при вставках, удалениях и иногда даже добавлениях; между тем, `LinkedList` использует узлы с двойной связью для хранения списка объектов, который вместо этого предлагает быструю итерацию, изменения на месте, а также вставку/удаление/добавление, но страшный случайный доступ. Эти два типа списков оптимизированы для разных вариантов использования, и это очень важно, как вы собираетесь их использовать. Когда вы пытаетесь выжать производительность из списка, с которым вы в большой степени взаимодействуете, и когда вы выбираете тип списка, вам следует тщательно выбрать, какой из них вы создаете.

С другой стороны, пользователям высокого уровня списка действительно не важно, как они реализованы, и они должны быть изолированы от этих деталей. Представьте себе, что Java не раскрывает интерфейс `List`, но имеет только конкретный класс `List`, который фактически является тем, что `LinkedList` сейчас. Все разработчики Java должны были настроить свой код для соответствия деталям реализации: избегать случайного доступа, добавлять кеш для ускорения доступа или просто переопределять `ArrayList` самостоятельно, хотя это было бы несовместимо со всем другим кодом, который действительно работает с `List`. Это было бы ужасно... Но теперь представьте себе, что мастера Java фактически понимают, что связанный список ужасен для большинства реальных случаев использования и решил перейти к списку массивов только для своего класса `List`. Это повлияет на производительность каждой Java-программы в мире, и люди не будут рады этому. И основным виновником является то, что детали реализации были доступны, и разработчики предположили, что эти детали являются постоянным контрактом, на который они могут положиться. Вот почему важно скрыть детали реализации и определить только абстрактный контракт. Это цель интерфейса: определить, какой тип ввода принимает метод, и какой вид вывода ожидается, не подвергая все кишки, которые заставляют программистов настраивать свой код, чтобы он соответствовал внутренним деталям, которые могут измениться при любом будущем обновлении.

Абстрактный класс находится в середине между интерфейсами и конкретными классами. Предполагается, что эта реализация поможет использовать общий или скучный код. Например, `AbstractCollection` предоставляет базовые реализации для `isEmpty` на основе размера 0, `contains` как повторение и сравнение, `addAll` как повторяющееся `add` и т.д. Это позволяет реализациям сосредоточиться на ключевых частях, которые различают их: как фактически хранить и извлекать данные.

###  API по сравнению с SPI

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

Абстрактные классы - это сильные помощники для использования при реализации интерфейса, предполагая некоторый уровень детализации реализации. Альтернативно, абстрактные классы используются для определения SPI, интерфейсов поставщика услуг.

Разница между API и SPI является тонкой, но важной: для API основное внимание уделяется тем, кто  **использует**, а для SPI основное внимание уделяется тому, кто  **реализует**.

Добавление методов в API легко, все существующие пользователи API все еще будут компилироваться. Добавление методов в SPI сложно, поскольку каждый поставщик услуг (конкретная реализация) должен будет внедрить новые методы. Если интерфейсы используются для определения SPI, провайдер должен будет выпускать новую версию всякий раз, когда изменяется контракт SPI. Если вместо этого используются абстрактные классы, новые методы могут быть либо определены в терминах существующих абстрактных методов, либо как пустые `throw not implemented exception` заглушки, которые, по крайней мере, позволят более старую версию реализации службы все еще компилироваться и выполняться.

###  Заметка о Java 8 и методах по умолчанию

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

###  Какой из них использовать?

* Должна ли существо быть  **публично использована** другими частями кода или другим внешним кодом? Добавьте к нему интерфейс, чтобы скрыть детали реализации из публичного абстрактного контракта, что является общим поведением вещи.
* Есть ли что-то, что должно иметь несколько реализаций с большим количеством общего кода? Сделайте как интерфейс, так и абстрактную, неполную реализацию.
* Будет ли только одна реализация, и никто ее не будет использовать? Просто сделайте это конкретным классом.
	+ "ever" - это долгое время, вы можете играть в нее безопасно и по-прежнему добавлять интерфейс поверх нее.

Следствие: другой путь часто ошибочно делается: при использовании вещи всегда старайтесь использовать наиболее общий класс/интерфейс, который вам действительно нужен. Другими словами, не объявляйте свои переменные как `ArrayList theList = new ArrayList()`, если у вас на самом деле не очень сильная зависимость от того, что он является  **массивом**, и ни один другой тип списка не сократит его для вас. Вместо этого используйте `List theList = new ArrayList` или даже `Collection theCollection = new ArrayList`, если на самом деле это список, а не какой-либо другой тип коллекции.

 

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

Интерфейс - это шаблон/шаблон методов (например, дается дом на бумаге (дом интерфейса), а разные архитекторы будут использовать свои идеи для его создания (классы архитекторов, реализующие интерфейс дома).
Это набор абстрактных методов, методов по умолчанию, статических методов, конечных переменных и вложенных классов.
Все участники будут либо окончательными, либо публичными, защищенными и частными спецификаторами доступа. Запрещено создание объекта.
Класс должен быть создан для использования интерфейса реализации, а также для переопределения абстрактного метода, объявленного в интерфейсе. Интерфейс является хорошим примером свободной связи (динамический полиморфизм/динамическое связывание)
Интерфейс реализует полиморфизм и абстракцию. Он рассказывает, что делать, но как это сделать, определяется классом реализации.
Напр. Там есть автомобильная компания, и она хочет, чтобы некоторые функции были одинаковыми для всего автомобиля, который он производит, поэтому для этого компания будет создавать интерфейсный автомобиль, который будет иметь эти функции и различные классы автомобилей (например, Maruti Suzkhi, Maruti 800). переопределить эти функции (функции).

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