Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

Интерфейс проигрывателя

В моих курсах Java я часто использую этот образ interface и спрашиваю: "Что это?"

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

Я обычно стараюсь избегать "контрактного" слова, которое может быть неправильно понято.

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

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

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

Ответ 2

Здесь хорошее сравнение двух: интерфейс против абстрактного класса. Я скопировал конкретный пример из ниже:

Интерфейс

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

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

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

Ответ 3

Интерфейс

Интерфейс - это просто спецификация. В нем описывается, что-то ДОЛЖНО делать. Ни больше ни меньше. Само по себе это бессмысленно. Это полезно только тогда, когда кто-то принимает эту спецификацию и реализует ее.

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

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

public interface IUSB
{
    Data Read();
    bool Write(Data data);
}

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

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

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

Я пытаюсь сделать что-то из хорошего реального мира и изо всех сил стараюсь, поэтому может реально составить пример кода.

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

public abstract class Employee
{
    public string FirstName { get; protected set; }
    public string LastName { get; protected set; }
    public string Grade { get; protected set; }
    public int Salary { get; protected set; }
    public abstract void GivePayRise();
}

У каждого сотрудника есть имя и соответствующий класс работы. Мы можем моделировать это в базовом классе с помощью первых 3 свойств. Однако предоставление бонуса не может быть простым делом, в зависимости от степени и т.д. Итак, мы отмечаем это как абстрактный. Каждый производный тип Employee (неполный рабочий день, полный рабочий день, контракт, консультант) должен реализовать это.

Реализация может быть:

public class FullTimeEmployee : Employee
{
    public void GivePayRise()
    {
        Salary *= 1.1;
    }
}

public class PartTimeEmployee : Employee
{
    public void GivePayRise()
    {
        Salary *= 1;
    }
}

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

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

Ответ 4

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

Теперь, чтобы перейти в ООП: ингредиент - это объект, так что это инструмент (чаша, нож, ложка и т.д.). Каждый из них имеет свойства (нож = handle_color: черный, blade_type: зазубренный и т.д.). И у каждого есть методы/действия, которые вы можете выполнять с ними (нож = разрез (перец)).

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

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

Итак, вы можете сделать некоторый псевдокод:

class pepper {
    var color
    var spiciness
    var size
}

class redPepper extends pepper {
    construct(){
        $this->color=red
    }
}

class cuttingKnife extends knife{
    construct(){
        $this->blade_type=serated
    }
}

class cookingPot extends pot{
    construct(){
        //We all know what a cooking pot is
    }
}

class stove extends apparatus{
    construct(){
        //We all know what a stove is
    }
}

$knife = new cuttingKnife();
$myPepper = new redPepper();
$pot = new cookingPot();
$stove = new stove();

$knife->cut($myPepper);
$pot->putOn($stove);
$stove->cookOn("high");
$pot->putIn("water");
$pot->putIn($myPepper);

//This will boil a cut pepper

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

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

Etc...

Ответ 5

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

Конкретный класс: Toshiba RC, Philips RC, JVC RC - что внутри коробки является конкретной реализацией.

Ответ 6

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

Интерфейс: дресс-код.

Ответ 7

Хорошим примером является калькулятор. Внутри калькулятора есть монтажная плата, которая имеет соединения между ее дисплеем, кнопками и логическим процессором.

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

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

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

КалькуляторBase, однако, не будет зависеть от конкретного дисплея, определенного набора кнопок или даже конкретной реализации логики. Вместо этого разработчик определяет интерфейс для каждого, например, ICalculatorDisplay. ICalculatorDisplay будет определять, как CalculatorBase ожидает взаимодействия с дисплеем. Тогда CalculatorBase будет работать с любым дисплеем, который реализует ICalculatorDisplay.

Ответ 8

(В некоторых языках абстрактный класс используется так же, как интерфейс, поэтому может быть запутанным)

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

  • ____ имеет крылья
  • Курица имеет крылья
  • Airbus A320 имеет крылья

Однако сами классы, в то время как все они могут соответствовать пробелу в предложении, не имеют никакого отношения между ними. Курица - птица, а Airbus A320 - это самолет. Единственное единство состоит в том, что у них обоих есть что-то, что мы называем "крыльями". (Вы также можете сказать, что истинные значения "крыльев" различны в двух ситуациях.)

class IHasWings : public IUnknown
{
public:
    // IUnknown methods: (Inherited)
    // IHasWings methods:
    virtual HRESULT GetWingSpan([out] double* pdblWingSpan) = 0;
    virtual HRESULT IsWingMovable([out] BOOL* pIsMovable) = 0;
    virtual HRESULT IsWingDetachable([out] BOOL* pIsDetachable) = 0;
};

class Chicken : public ... ..., public IHasWings
{
};

class AirbusA320 : public ... ..., public IHasWings
{
};

Ответ 9

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

В то время как абстрактный класс мог бы определить один из моих талантов, например, играть на гитаре. Проблема в том, что "игра на гитаре" сама по себе на самом деле не так полезна. Но мы могли бы использовать эту способность для создания типа человека, такого как музыкант (который мы могли бы назвать классом).