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

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

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

20
задан Community 23 May 2017 в 11:51
поделиться

8 ответов

Интерфейс плеера

На моих курсах по Java я часто использую это interface изображение и спрашиваю: «Что это?»

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

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

DVD-проигрыватель Абстрактный класс

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

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

35
ответ дан 29 November 2019 в 22:50
поделиться

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

Интерфейс

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

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

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

21
ответ дан 29 November 2019 в 22:50
поделиться

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

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

  • ____ имеет крылья
  • У цыпленка есть крылья
  • У 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
{
};
0
ответ дан 29 November 2019 в 22:50
поделиться

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

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

0
ответ дан 29 November 2019 в 22:50
поделиться

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

Теперь перейдем к ООП: ингредиент - это объект, так же как и инструмент (миска, нож, ложка и т. Д.). У каждого из них есть свойства (нож = 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 (потому что она особенная).

И т.д. ...

1
ответ дан 29 November 2019 в 22:50
поделиться

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

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

1
ответ дан 29 November 2019 в 22:50
поделиться

Интерфейс

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

Подумайте о 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();
}

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

Реализация может быть следующей:

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

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

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

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

3
ответ дан 29 November 2019 в 22:50
поделиться

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

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

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

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

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

0
ответ дан 29 November 2019 в 22:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: