Відмінності абстрактного класу від інтерфейсу (abstract class and interface) - stack overflow російською
Абстрактний клас - це клас, у якого не реалізований один або більше методів (деякі мови вимагають такі методи позначати спеціальними ключовими словами).
Інтерфейс - це абстрактний клас, у якого ні один метод не реалізований, всі вони публічні і немає змінних класу.
Інтерфейс потрібен зазвичай коли описується тільки інтерфейс (тавтологія). Наприклад, один клас хоче дати іншому можливість доступу до деяких своїх методів, але не хоче себе «розкривати». Тому він просто реалізує інтерфейс.
Абстрактний клас потрібен, коли потрібно сімейство класів, у яких є багато спільного. Звичайно, можна застосувати і інтерфейс, але тоді потрібно буде писати багато ідентичного коду.
У деяких мовах (С ++) спеціального ключового слова для позначення інтерфейсів немає.
Можна вважати, що будь-який інтерфейс - це вже абстрактний клас, але не навпаки.
tl; dr: Абстрактний клас - засіб розробки класів на нижньому рівні, засіб для повторного використання коду; інтерфейс - засіб вираження семантики класу. Таким чином, це абсолютно різні, мало пов'язані між собою поняття.
Абстрактний клас - це «заготовка» класу: реалізовано більшість методів (включаючи внутрішні), крім кількох. Ці кілька нереалізованих методів цілком можуть бути внутрішніми методами класу, вони лише уточнюють деталі імплементації. Абстрактний клас - засіб для повторного використання коду, засіб, щоб вказати, який алгоритм повинен бути перекритий для завершення написання класу.
Інтерфейс ж - це свого роду контракт: інтерфейси використовуються в визначеннях щоб вказати, що об'єкт, який буде використаний на самому справі, повинен реалізовувати (для вхідних параметрів) або буде гарантовано реалізовувати (для вихідних параметрів) набір методів і (що набагато важливіше!) мати певну семантику. Інтерфейс цілком може бути і порожнім, тим не менш, імплементувати інтерфейс означає підтримувати цю семантику.
Абстрактні класи ідеологічно схожі з шаблонами C ++: і ті, і інші є заготовками класів, але шаблоном для отримання класу потрібно уточняти шаблонні типи, а абстрактного класу - абстрактні методи.
Інтерфейси ідеологічно схожі з заголовками файлами C ++: вони розкривають методи і приховують конкретну реалізацію.
Питання про те, чи є інтерфейс або абстрактний клас власне класом - технічна подробиця реалізації, що залежить від конкретної мови програмування. Наприклад, в C ++ інтерфейси відсутні зовсім, і їх доводиться емулювати класами без даних. Абстрактний клас в C ++ як такої також відсутня, але їм можна вважати будь-який клас з абстрактними методами. (Звідси обмеження C ++: як мінімум 1 абстрактний метод в абстрактному класі.) Також в C ++ можна (непрямо) інстанцііровать абстрактний клас, викликати абстрактний метод і (можливо) отримати помилку часу виконання. У C # інтерфейси і абстрактні класи вбудовані в мову.
Приклад (на C #, конкретну мову значення не має):
Мені здається досить цікавим, що дане питання позначений тегом «ООП», але при цьому у багатьох відповідях явно просочуються специфічні аспекти конкретних мов програмування. Я ж постараюся дати відповідь виходячи з понять ООП і лише потім показати, чому взагалі ця різниця з'явилося в деяких мовах програмування.
Абстрактні класи та інтерфейси мають певне відношення до спадкоємства, точніше до моделювання світу. З їх допомогою ми хочемо висловити, що у певної групи речей в нашій системі є щось спільне: деяке загальне поведінка, яке відрізняє цю групу штуковин від всіх інших.
Припустимо, для прикладу, ми хочемо змоделювати кнопки в інтерфейсі користувача. Оскільки ми говоримо про ООП, то ми виділимо певний тип Кнопки з деяким набором операцій (які визначають поведінку) і прихованого стану, на яке спирається поведінку (так, прихованого стану може і не бути). При цьому ми можемо виділити три види операцій:
Конкретна фіксована операція, яка повинна бути абсолютно стабільно для всіх типів кнопок.
Конкретна операція з поведінкою за замовчуванням (тобто операція, чия поведінка підходить для багатьох типів кнопок, але можуть бути кнопки з іншим поведінкою).
Декларація операції без конкретної реалізації (тобто операція, чия поведінка визначити неможливо, оскільки на цьому етапі не відомо розумна поведінка за умовчанням або ж операції можуть занадто сильно відрізнятися у різних кнопок).
Іншими словами, тип Кнопки може містити невіртуальні методи (non-virtual methods), віртуальні методи (virtual methods) і абстрактні методи (abstract methods).
Наявність різних типів методів є дуже важливим інструментом моделювання і дозволяє досить точно виражати наміри проектувальника. Наприклад, ми можемо додати невіртуальну операцію «Натискання на кнопку», яка буде делегувати частину своєї роботи віртуального (або абстрактного методу) «Обробити натискання», але при цьому завжди виконувати певну частину роботи (прозорливий Новомосковсктель побачить в цьому описі патерн «Шаблоновий метод» ).
Після того, як ми визначили базовий тип, прийшов час визначити довільні типи. І тут починаються питання. Точніше, питань ніяких не виникає, коли у типу є лише один безпосередній базовий тип або всі базові типи містять лише декларації операцій. Не проблема, успадкувати «Кнопку меню» від «Кнопки» і перевизначити метод «Натиснути на кнопку». Але що, якщо наш тип «Кнопка меню» буде отнаследован від двох типів з однієї і тієї ж віртуальної операцією? Як перевизначити лише одну, а залишити іншу? А як бути клієнту нового типу і розрізнити, яку операцію викликати? А що якщо у двох базових типів є поле з одним ім'ям? А що якщо в одного базового типу метод «Натиснути кнопку» реалізований, а в іншого - лише описаний у вигляді декларації?
Тепер буде легко провести різницю між трьома поняттями - інтферфейса, абстрактного базового класу і конкретного базового класу.
Інтерфейс - описує деяке сімейство типів і містить лише декларації операцій (так, я усвідомлено пишу слово «декларація», а не використовую слово «контракт», яке в ООП має цілком певне значення).
Абстрактний базовий клас описує деяке сімейство типів, але крім декларації операцій може містити реалізації за замовчуванням (віртуальні методи) і фіксовані операції (невіртуальні методи).
Конкретний клас описує деяке сімейство типів, яке готове для використання клієнтами. Такий клас не може містити декларації операцій і всі його операції повинні бути або фіксованими (невіртуальні методи) або містити реалізацію за замовчуванням (віртуальні методи). Є ще один підвид конкретних класів - запечатаний (sealed) клас - це різновид конкретного класу отнаследоваться від якого неможливо, а значить він може містити лише конкретні операції.
Інтерфейси ж, за своєю природою мають меншу связностью (low coupling), оскільки не володіють конкретною поведінкою, яке може ускладнити життя класу-спадкоємця. Інтерфейси також можуть моделювати відношення «Є» ( «Кнопка меню» Є «IКнопкой»), але можуть визначати і менш жорстке ставлення «Може виконувати роль» (CAN DO). Наприклад, інтерфейс IEquatable з BCL визначає «додаткове» поведінку, яке говорить про можливість типів порівнювати значення об'єктів.
Давайте по порядку. Інтерфейс - це договір / об'язательства, які бере на себе клас і зобов'язаний їх виконати. Припустимо: є масив класів, які вміють вітатися
Тепер будь-який клас незалежно від його складності ієрархії і обсягу може успадкувати (взяти на себе об'язательство / підписати контракт на виконання) даного методу і тим самим "стане своїм через чужих". Найприємніше тут те, що яким би великим би не був інтерфейс (в даному контексті є публічні методи класу) у класу виконує даний контракт - з цього масиву буде бачити тільки один метод. Приклад: є багато графічних класів і деякі з них ви навчили реагувати на Blur - запіхну їх в 1 масив інтерфейсів і при потребі викликайте метод Blur (int value); При використанні інтерфейсу, ми абстрагуємося від того, що за клас: машина, рослина, повітря. Якщо він взяв на себе зобов'язання мати реалізацію "Привітатися" у нас є гарантія. що даний метод буде нам доступний через об'єкт (покажчик даного класу) (нагадую, інтерфейс чістовіртуальние методи, в паблік секції, без змінних).
А тепер інша сторона, С ++ при всьому своєму могутність не має поняття інтерфейс на рівні мови. Але програмісти звикли до інтерфейсу, це зручно, це безпечно (почитайте про Insersion of control) і правильно (з точки зору архітектури). Доводиться реалізовувати "інтерфейс" тими інструментами, що пропонує мову С ++ - це абстракний клас. Як ви помітили, туди можна запхати різні методи (public / protected / private), клас-мемберов (в інших мовах за змінні в інтерфейсі вже проблеми). Було б ключове слово interface в С ++ і наслідувала б виразно як в C # - такий б плутанини не було. Абстрактні класи, як раз, і застосовуються у випадках виділення загальної частини класів, але самого такого класу як би не повинно бути (це безглуздий мати екземпляр такого класу).
Як приклад, описували класи м'яч і кавун, знайшли спільні риси, побачили, що ще будуть описувати круглі предмети. Виділили все це в загальний клас і зробили його абстрактним, тому що навіщо в системі мати можливість мати клас "Щось кругло, з вагою і можна кинути".
клас з віртуальною функцією / функціями називається - абстрактним
абстрактний клас може мати одну або кілька чисто віртуальних функцій
якщо абстрактний клас має хоча б одну чисто віртуальну функцію, об'єкт такого класу не можна створювати, а тільки наслідувати причому чисто віртуальні функції повинні бути перевизначені в майбутньому.
інтерфейс класу - це вказівка / договір з програмістом про те, як програміст може використовувати цей клас. тобто виходить інтерфейс - це все відкриті (public) дані до яких може звернутися програміст.
по суті написав що і @VladD тільки простою мовою