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

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

30 ответов


интерфейсы

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

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

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

// 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;
    }
}

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


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

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

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

например:

// 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 _ _ methods).

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


основные технические различия между абстрактный класс и интерфейс являются:

  • абстрактные классы могут иметь константы, члены, заглушки методов (методы без тела) и определенные методы, тогда как интерфейсы могут иметь только константы и методы заглушки.

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

  • при наследовании абстрактного класса A б дочерний класс необходимо определить абстрактные методы, тогда как абстрактный класс может расширить другой абстрактный класс, и абстрактные методы из родительского класса не должны быть определены.

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

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

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


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

enter image description here

приняты от:

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-c-net.html


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

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

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

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


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

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

Difference

As заявил Джо из javapapers:

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

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

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

4.Интерфейс Java должен быть реализован с помощью ключевого слова "implements"; абстрактный класс Java должен быть расширен с помощью ключевого слова"extends".

5.Интерфейс может расширить только другой интерфейс Java, абстрактный класс может расширить другой класс Java и реализовать несколько Java межфазные границы.

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

7.Интерфейс абсолютно абстрактен и не может быть создан; абстрактный класс Java также не может быть создан, но может быть вызван, если главная() существует.

8.По сравнению с абстрактными классами java, интерфейсы java медленны, поскольку это требует дополнительного косвенного подхода.


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

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

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

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

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

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

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

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

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

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

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

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

обратитесь к этой документации страница для получения более подробной информации.

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

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


самое главное:

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

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

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


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

чертеж здания интерфейс

  • например, Servlet (I)

здание построено до 200 этажей-частично завершено - - -аннотация

  • частичная реализация, например, generic и HTTP servlet
строительство!--3-->б
  • полный реализация, например, собственного сервлета

интерфейс

  • мы ничего не знаем о реализации справедливых требований. Мы можем перейти к интерфейсу.
  • каждый метод public и Abstract по умолчанию
  • это 100% чистый абстрактный класс
  • если мы объявляем публичным, мы не можем объявить частным и защищенным
  • если мы объявляем абстрактное, мы не можем объявить окончательное, статическое, синхронизированное, strictfp и родной
  • каждый интерфейс имеет публичный, статический и окончательный
  • сериализация и переходный процесс неприменимы, потому что мы не можем создать экземпляр для in interface
  • энергонезависимый, потому что он окончательный
  • каждая переменная является статической
  • когда мы объявляем переменную внутри интерфейса, нам нужно инициализировать переменные при объявлении
  • экземпляра и статический блок не разрешено

Аннотация

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

взято с сайта DurgaJobs


давайте снова поработаем над этим вопросом:

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

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

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

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


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

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

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

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

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

и последнее,

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

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

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

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

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


сравнение интерфейса и абстрактного класса неверно. Вместо этого должно быть два других сравнения: 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-aware box - я знаю, как проверить свою позицию на карта:

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 или C++, можно иметь просто класс, ни абстрактный, ни окончательный. Такой класс может быть унаследован и может быть создан. Я не думаю, что это строго соответствует объектно-ориентированной парадигме.

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


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

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

интерфейсы были введены в Java из-за проблема Алмаз множественного наследования и что они на самом деле намереваемся сделать.

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

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


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

Синтаксические Различия Между интерфейс и Абстрактный Класс:

  1. методы и члены абстрактного класса могут иметь любой видимости. Все методы интерфейс должно быть общественные. / / больше не выполняется с Java 9
  2. конкретный класс ребенка Аннотация класс должен определить все абстрактный метод. Ан Аннотация дочерний класс может иметь абстрактные методы. Ан интерфейс расширение другого интерфейса не должно обеспечивать реализацию по умолчанию для методов, унаследованных от родительского интерфейса.
  3. дочерний класс может расширять только один класс. Ан интерфейс можно расширить несколькими интерфейсами. Класс может реализовать несколько интерфейсов.
  4. дочерний класс может определять абстрактные методы с тем же или менее ограничительная видимость, тогда как класс, реализующий интерфейс должны определить все методы интерфейса как public.
  5. Абстрактные Классы могут иметь конструкторы, но не интерфейсы.
  6. интерфейсы из Java 9 имеют частные статические методы.

в интерфейсы:

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


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

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

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

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


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

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


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

ниже примеры демонстрируют это.

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

abstract class animals
{
    // They all love to eat. So let's 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 может иметь обычные вкусы членов класса, таких как private, protected и т. д..


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

  • разрешить объекту рассматривать элементы данных родительского типа и реализации методов как свои собственные.

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

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

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

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


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

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

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

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

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


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

  1. полностью абстрактный, кроме default и static методы; в то время как он имеет определения (сигнатуры методов + реализации) для default и static методы, он имеет только объявления (подписи методов) для других методов.
  2. С учетом более слабых правил, чем классы (класс может реализовать несколько interfaces иinterface может наследовать из нескольких interfaces). Все переменные неявно константа, указывается ли как public static final или нет. Все члены неявно public, указано ли как таковое или нет.
  3. обычно используется как гарантия того, что класс реализации будет иметь указанные функции и/или будет совместим с любым другим классом, который реализует тот же интерфейс.

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

  1. где угодно от полностью абстрактного до полностью реализованного, с тенденцией иметь один или несколько abstract методы. Может содержать как объявления, так и определения с объявлениями, помеченными как abstract.
  2. полноценный класс и подчиняется правилам, которые управляют другими классами (может наследовать только от одного класса), при условии, что он не может быть создан (потому что нет никакой гарантии, что он полностью реализован). Может иметь непостоянные переменные-члены. Может реализовывать управление доступом членов, ограничивая членов как protected, private, или отдельный пакет (неопределенный.)
  3. обычно используется либо для предоставления столько реализации, сколько может быть разделено несколькими подклассами, либо для предоставления столько реализации, сколько программист может предоставить.

или, если мы хотим свести все это к одному предложению: An interface Это то, что класс, реализующий и, а abstract класс как подкласс is.


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

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

резюме

  1. интерфейс определяет контракт что некоторая реализация выполнит для вас.

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

альтернативный резюме

  1. интерфейс предназначен для определения общедоступных API
  2. абстрактный класс предназначен для внутреннего использования и для определения SPIs

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

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

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

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

APIs против SPIs

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

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

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

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

примечание по Java 8 и методам по умолчанию

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

какую использовать?

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

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


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

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

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

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

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


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


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

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

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

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

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

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

 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");
        }
    }

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

интерфейс

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

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

  • абстрактный класс содержит абстрактные и не абстрактные методы.

  • не заставляет пользователей реализовывать все методы при наследовании абстрактный класс.

  • содержит все виды переменных, включая примитивные и не примитивный

  • объявить с помощью абстрактного ключевого слова.

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

  • дочерний класс может расширять только один класс (абстрактный или конкретный).


enter image description here

вот очень базовое понимание интерфейса против абстрактного класса.


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

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

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


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

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


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

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


Я прочитал простое, но эффективное объяснение абстрактного класса и интерфейса на php.net

что выглядит следующим образом.

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

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

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

абстрактный класс является основой для другого объекта. Когда класс говорит: "я расширяю абстрактный класс Y", он говорит:"Я использую некоторые методы или свойства, уже определенные в этом другом классе с именем Y".

Итак, рассмотрим следующий PHP:

<?php
class X implements Y { } // this is saying that "X" agrees to speak language "Y" with your code.

class X extends Y { } // this is saying that "X" is going to complete the partial class "Y".
?>

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

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

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