Яка різниця між інтерфейсом і класом, і чому я повинен використовувати інтерфейс, коли я можу реалізувати методи безпосередньо в класі?


117

Я знаю, що це дуже основне запитання, але інтерв'юер задав мене дуже хитро, і я був безпорадний :(

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

Я також не розумію жодної речі в інтерфейсі. наприклад, ми використовуємо

conn.Dispose();нарешті блок. Але я не бачу, щоб клас мав на увазі клас реалізації чи успадковування IDisposableінтерфейсу ( SqlConnection). Мені цікаво, як я можу просто назвати ім'я методу. Крім того, я не розумію, як працює метод Dispose, тому що нам потрібно реалізувати функціональний орган із власною реалізацією для всіх методів інтерфейсу. То як інтерфейси приймаються або називаються контрактами? Ці питання, що тривали в моїй свідомості дотепер, і відверто кажучи, я ніколи не бачив жодної хорошої нитки, яка б пояснювала мої питання таким чином, щоб я міг зрозуміти.

MSDN, як завжди, виглядає дуже страшно, і жоден рядок там не зрозумілий ( Люди, люб'язно вибачте, хто перебуває на високому рівні розвитку, я настійно вважаю, що будь-який код чи стаття повинні дійти до уваги кожного, хто бачить його, отже, як кажуть багато інших, MSDN не корисний ).

Інтерв'юер сказав:

У нього є 5 методів, і він із задоволенням реалізує це у класі безпосередньо, але якщо вам доведеться перейти на клас Анотація або інтерфейс, який саме ви обираєте і чому? Я відповів йому на всі речі, які я читав у різних блогах, кажучи про переваги та недоліки як абстрактного класу, так і інтерфейсу, але він не переконаний, він намагається зрозуміти "Чому інтерфейс" взагалі. "Чому абстрактний клас" взагалі, навіть якщо я можу реалізувати ті самі методи лише один раз і не хочу його змінювати.

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


4
Інтерфейси - це я теж намагався зрозуміти. Гарне питання.
Брайан

4
програмування до абстрактного контракту, а не конкретної реалізації .... Словом, це означає, що ви можете замінити будь-який об'єкт, що реалізує інтерфейс, коли потрібен інтерфейс.
Мітч Пшеничний

7
SqlConnectionуспадковує System.ComponentModel.Componentякий реалізує IDisposable.
Лі

2
@MitchWheat - Це не призначено для прикладу, питання задає, як SqlConnectionреалізує IDisposable.
Лі

О Лі, це змусило мене зрозуміти дякую. Але я все ще не бачу, як і де визначено функціональність методу "розпорядження".
Учень

Відповіді:


92

Інтерфейси чудові, коли ви хочете створити щось подібне:

using System;

namespace MyInterfaceExample
{
    public interface IMyLogInterface
    {
        //I want to have a specific method that I'll use in MyLogClass
        void WriteLog();       
    }

    public class MyClass : IMyLogInterface
    {

        public void WriteLog()
        {
            Console.Write("MyClass was Logged");
        }
    }

    public class MyOtherClass : IMyLogInterface
    {

        public void WriteLog()
        {
            Console.Write("MyOtherClass was Logged");
            Console.Write("And I Logged it different, than MyClass");
        }
    }

    public class MyLogClass
    {
        //I created a WriteLog method where I can pass as a parameter any object that implements IMyLogInterface.
        public static void WriteLog(IMyLogInterface myLogObject)
        {
            myLogObject.WriteLog(); //So I can use WriteLog here.
        }
    }

    public class MyMainClass
    {
        public void DoSomething()
        {
            MyClass aClass = new MyClass();
            MyOtherClass otherClass = new MyOtherClass();

            MyLogClass.WriteLog(aClass);//MyClass can log, and have his own implementation
            MyLogClass.WriteLog(otherClass); //As MyOtherClass also have his own implementation on how to log.
        }
    }
}

У моєму прикладі я міг би бути розробником, який пише MyLogClass, а інші розробники могли створювати свої класи, і коли вони хотіли увійти, вони реалізують інтерфейс IMyLogInterface. Саме вони запитували мене, що їм потрібно реалізувати для використання WriteLog()методу MyLogClass. Відповідь вони знайдуть в інтерфейсі.


3
Ей, це виглядає як дуже хороший інгредієнт для мене, щоб зрозуміти, я дуже це вдячний, велике спасибі :) :)
Учень

14
Моє запитання, якщо ви створюєте інстанцію, MyClassі MyOtherClassчому б ви просто не зателефонували, aClass.WriteLog()чому додати цей додатковий крок? Реалізація WriteLog()буде залишатися різною для кожного з класів, але у вас вже є об'єкт, тому навіщо передавати його класу обробника?
Зак М.

Хм, може бути, якщо ви помістите свій приклад журналу на самородок, що для інших було б простіше використовувати ваш реєстратор, не знаючи деталей .. але, з іншого боку, все-таки це не якийсь універсальний клас, (може я можу написати інтерфейс з протоколом реєстрації та рівнями тривоги) інтерфейси все ще знаходяться лише в межах вашої сфери. тож крім себе, хто від цього виграє ?.
користувач3800527

2
@ZachM. Якщо я правий, відповідь означає, що він не буде інстанціювати класи, але інші розробники інстанціюють класи та передадуть його як параметр MyLogClass WriteLogметоду. Таким чином, його метод може обробляти будь-який об'єкт, який реалізує IMyLogInterface. Ось ще один цікавий пост.
shaijut

1
Моє запитання, чому інтерфейс ??? Наведений вище сценарій також може бути досягнутий абстрактним класом з усіма абстрактними методами.
Abhijit Ojha

52

Однією з причин, що я використовую інтерфейси, є те, що це збільшує гнучкість коду. Скажімо, ми отримали метод, який приймає об'єкт класу типу Account як параметр, наприклад:

public void DoSomething(Account account) {
  // Do awesome stuff here.
}

Проблема з цим полягає в тому, що параметр методу зафіксовано до реалізації облікового запису. Це добре, якщо вам ніколи не потрібен будь-який інший тип рахунку. Візьмемо цей приклад, який замість цього використовується параметр інтерфейсу облікового запису.

public void DoSomething(IAccount account) {
  // Do awesome stuff here.
}

Це рішення не орієнтоване на реалізацію, а це означає, що я можу передати йому SuperSavingsAccount або ExclusiveAccount (обидва реалізуючи інтерфейс IAccount) та отримати іншу поведінку для кожного реалізованого облікового запису.


45

Інтерфейси - це договори, яких повинні дотримуватися виконавці. Абстрактні класи дозволяють укладати контракти плюс спільні реалізації - те, що інтерфейси не можуть мати. Класи можуть реалізовувати та успадковувати декілька інтерфейсів. Заняття можуть поширювати лише один абстрактний клас.

Чому інтерфейс

  • У вас немає реалізації коду за замовчуванням або спільного використання
  • Ви хочете ділитися договорами передачі даних (веб-сервіси, SOA)
  • У вас є різні реалізації для кожного реалізатора інтерфейсу ( IDbCommandмає SqlCommandта OracleCommandякий реалізує інтерфейс конкретними способами )
  • Ви хочете підтримати багаторазове успадкування .

Чому абстрактно

  • У вас є реалізація коду за замовчуванням або спільний доступ
  • Ви хочете мінімізувати дублювання коду
  • Ви хочете легко підтримувати версії

2
@Silver Я читаю більшість того, що ти набрав у блогах, але намагаюся зрозуміти практично. Я робив сервіси WCF, відкривав інтерфейси (але це був лише окремий окремий додаток, без вхідного або нижнього течії). Отже, я не міг зрозуміти це належним чином, хоча я дуже добре розробив та реалізував інтерфейси. Моє запитання полягає в тому, що ви практично поділитесь методом імен методу, який означає, чи не так? ЯК ЦЕ КОРИСНО :( Я знаю, що це просто змушує реалізувати всі методи, але як ще? У вашій публікації вище про інтерфейс, 2-й пункт каже поділитися, значить, ви можете навести практичний приклад цього в реальному часі
Учень

1
Для практичного прикладу щодо інтерфейсів та SOA ми ділимося нашими WCF-інтерфейсами ( DataContracts) в .NET зборі ( наприклад, Contracts.Shared.dll ), щоб споживачі .NET-клієнтів могли легко взаємодіяти, використовуючиChannelFactory ( уникаючи генерації коду через Add Service Reference тощо). ) або за допомогою довідкової служби служби із загальними типами
SliverNinja - MSFT

Якщо я оголошу лише абстрактні методи всередині абстрактного кальсу, то абстрактний клас буде виконувати функції інтерфейсу, то навіщо нам потрібен інтерфейс?
Abhijit Ojha

25

введіть тут опис зображення

Отже, у цьому прикладі PowerSocket нічого іншого не знає про інші об'єкти. Усі об'єкти залежать від потужності, що надається PowerSocket, тому вони реалізують IPowerPlug, і таким чином вони можуть підключитися до нього.

Інтерфейси корисні, оскільки вони надають договори, які об’єкти можуть використовувати для спільної роботи, не потребуючи нічого іншого знати.


Це має сенс, але я все ще намагаюся зрозуміти, чи не могли б ви просто створити базовий клас для PowerSocket і всі ті інші речі успадкувати його за потреби. Технічно розетки не мають уявлення про інші класи.
altaaf.hussein

Я думаю, тому що багаторазове успадкування заборонено в C #
Х'ю Seagraves

22

Одним словом - через поліморфізм !

Якщо ви "Програмуєте на інтерфейс, а не на реалізацію", тоді ви можете вводити різні аргументи, які поділяють один і той же інтерфейс (тип) в якості аргументу. Таким чином ваш код методу не поєднується з будь-якою реалізацією іншого класу, що означає, що він завжди відкритий для роботи з новоствореними об'єктами одного інтерфейсу. (Принцип відкриття / закриття)

  • Погляньте на ін'єкцію залежностей та обов'язково прочитайте шаблони дизайну - елементи багаторазового об’єктно-орієнтованого програмного забезпечення від GOF.

4

У C # немає набору качок - це лише тому, що ви знаєте, що певний метод реалізований у наборі конкретних класів, не означає, що ви можете ставитись до них однаково щодо виклику цього методу. Реалізація інтерфейсу дозволяє вам ставитися до всіх класів, що реалізують його, як до одного типу речей, щодо того, що визначає цей інтерфейс.


3
Ви можете отримати сорт каченя в .net4 з динамічним типом.
Тоні Хопкінсон

4

Я вважаю, що багато запитували кров, задаючи ці питання, і багато хто намагається вирішити цю проблему, пояснивши терміни, подібні до роботи, які не може зрозуміти жодна нормальна людина.

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

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

У вас є клас транспортного засобу, який може змінюватися за потреби користувача (наприклад, додавання вантажівки , цистерни , літака тощо)

public class clsBike:IChoice
{
   #region IChoice Members
    public string Buy()
    {
       return ("You choose Bike");
    }
    #endregion
}

і

public class clsCar:IChoice
{
   #region IChoice Members
    public string Buy()
    {
       return ("You choose Car");
    }
    #endregion
}

і в обох є контракт IChoice, який просто каже, що Мій клас повинен мати метод Buy

public interface IChoice
{
    string Buy();
}

Тепер, бачите, цей інтерфейс застосовує лише метод, Buy()але нехай спадковий клас вирішує, що робити, коли він реалізує його. Це обмеження інтерфейсу, використовуючи суто інтерфейс, ви можете в кінцевому підсумку повторити якусь задачу, яку ми можемо реалізувати автоматично, використовуючи abstact. На нашому прикладі, скажімо, при покупці кожного транспортного засобу знижка.

public abstract class Choice
{
    public abstract string Discount { get; }
    public abstract string Type { get; }
    public string Buy()
    {
       return "You buy" + Type + " with " + Discount;
}
public class clsBike: Choice
{
    public abstract string Discount { get { return "10% Discount Off"; } }
    public abstract string Type { get { return "Bike"; } }
}

public class clsCar:Choice
{
    public abstract string Discount { get { return " $15K Less"; } }
    public abstract string Type { get { return "Car"; } }
}

Тепер, використовуючи заводський клас, ви можете досягти того самого, але, використовуючи абстрактне, ви дозволяєте базовому класу виконувати Buy()метод.

Підсумок: Договори інтерфейсу дозволяють класу успадковувати виконувати реалізацію, тоді як контракти абстрактного класу можуть ініціалізувати реалізацію (яка може переосмислювати клас спадкування )


2

За допомогою інтерфейсу ви можете зробити наступне:

1) Створіть розділені інтерфейси, які пропонують різні скорочення вашої реалізації, що забезпечує більш згуртований інтерфейс.

2) Дозволити кілька методів з однаковою назвою між інтерфейсами, тому що ей, у вас немає конфліктної реалізації, а лише підпис.

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

4) Ваш код може покладатися на абстракцію, а не на конкретування, що дозволяє інтелектуально вводити залежність, включаючи інжекторні тестові макети тощо.

Є багато інших причин, я впевнений, це лише кілька.

Абстрактний клас дозволяє мати частково конкретну базу для роботи, це не те саме, що інтерфейс, але має свої якості, такі як здатність створювати часткову реалізацію за допомогою шаблону шаблону методу.


Ви нехтуєте найважливішим: реалізація інтерфейсу робить ваш клас корисним для використання будь-яким кодом, який потребує реалізації цього інтерфейсу, без необхідного коду нічого знати про ваш клас.
supercat

2

Як справжній зразок відповіді @ user2211290:

І те, ArrayіList мають інтерфейс IList. Нижче ми маємо a string[]і a List<string>і перевіряємо їх обох одним методом за допомогою IList :

string[] col1 = { "zero", "one", "two", "three", "four"};
List<string> col2 = new List<string>{ "zero", "one", "two", "three"};

//a methode that manipulates both of our collections with IList
static void CheckForDigit(IList collection, string digit)
{
    Console.Write(collection.Contains(digit));
    Console.Write("----");
    Console.WriteLine(collection.ToString()); //writes the type of collection
}

static void Main()
{
    CheckForDigit(col1, "one");   //True----System.String[]
    CheckForDigit(col2, "one");   //True----System.Collections.Generic.List`1[System.String]



//Another test:

    CheckForDigit(col1, "four");   //True----System.String[]
    CheckForDigit(col2, "four");   //false----System.Collections.Generic.List`1[System.String]
}

1

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

Перевагою абстрактного класу було б те, що ви можете мати базову реалізацію. Однак у випадку IDisposable реалізація за замовчуванням марна, оскільки базовий клас не знає, як правильно очистити речі. Таким чином, інтерфейс був би більш підходящим.


1

І абстрактний клас, і інтерфейс є контрактами.

Ідея договору полягає в тому, щоб ви вказали певну поведінку. Якщо ви скажете, що виконали, то погодилися на контракт.

Вибір абстрактного по інтерфейсу є.

Будь-який не абстрактний нащадок абстрактного класу буде виконувати контракт.

проти

Будь-який клас, який реалізує інтерфейс, реалізує контракт.

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


1

Інтерфейси - це зробити абстракцію (архетип) абстракції (класи) реальності (об'єкти).

Інтерфейси мають визначати умови контракту, не забезпечуючи впровадження класів.

Інтерфейси - це специфікації:

  • Інтерфейси - це артефакти часу проектування, щоб визначити нерухому поведінку концепції як самої та статичної.

  • Класи - це артефакти часу впровадження для визначення мобільної структури реальності під час її взаємодії та руху.

Що таке інтерфейс?

Коли ви спостерігаєте за котом, ви можете сказати, що це тварина, яка має чотири лапи, голову, тулуб, хвіст і шерсть. Ви можете бачити, що він може ходити, бігати, їсти та мяукати. І так далі.

Ви щойно визначили інтерфейс з його властивостями та його операціями. Як такий, ви не визначили жодного способу роботи, а лише функції та можливості, не знаючи, як все працює: ви визначили здібності та відмінності.

Як такий, він насправді ще не клас, хоча в UML ми називаємо це класом на класовій діаграмі, оскільки ми можемо визначити приватних та захищених членів, щоб почати глибокий вигляд артефакту. Не плутайте тут, оскільки в UML інтерфейс - дещо інша річ, ніж інтерфейс у C #: це як точка часткового доступу до атома абстракції. Як такий, ми говорили, що клас може реалізувати кілька інтерфейсів. Як таке, це те саме, але ні, тому що інтерфейси в C # використовуються як для абстрагування абстракції, так і для обмеження цієї абстракції як точки доступу. Це два різні способи використання. Таким чином, клас в UML являє собою повний інтерфейс зв'язку до класу програмування, тоді як інтерфейс UML являє собою інтерфейс для роз'єднання розділу класу програмування. Дійсно, діаграма класів в UML не піклується про реалізацію, і всі її артефакти знаходяться на рівні інтерфейсу програмування. У той час як ми відображаємо класи UML на класи програмування, це перенесення абстрактної абстракції в конкретну абстракцію. Існує тонкощі, яка пояснює дихотомію між областю дизайну і полем програмування. Таким чином, клас в UML - це клас програмування з точки зору інтерфейсу програмування при розгляді внутрішніх прихованих речей.

Інтерфейси також дозволяють моделювати багато успадкованих, коли вони недоступні. Наприклад, клас котів буде реалізовувати інтерфейс котів, який походить від інтерфейсу для тварин. Цей клас котів також буде реалізовувати такі інтерфейси: ходити, бігати, їсти та видати звук. Це компенсує відсутність багаторазового успадкування на рівні класу, але кожен раз, коли вам потрібно все повторно реалізовувати, і ви не можете фактурувати реальність у кращому випадку, як це робить сама реальність.

Щоб зрозуміти, що ми можемо звернутися до кодування об'єкта Pascal, де ви визначаєте в блоці інтерфейс та розділи реалізації. В інтерфейсі ви визначаєте типи, а в реалізації реалізуєте тип:

unit UnitName;

interface

type
  TheClass = class
  public
    procedure TheMethod;
  end;

implementation

class procedure TheClass.TheMethod;
begin
end;

Тут розділ інтерфейсу відповідає дизайну класу UML, тоді як типи інтерфейсів - це інші речі.

Тож у нашому бізнесі у нас є одне слово, інтерфейс , щоб визначити дві чіткі, але схожі речі, і це є джерелом плутанини.

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

Зрештою, інтерфейси необхідні для того, щоб несумісні системи могли спілкуватися, не турбуючись про реалізацію та управління об'єктами в пам'яті, як, наприклад, представлені з (розподіленою) загальною об'єктною моделлю.

Що таке клас?

Визначивши зменшення реальності із зовнішньої точки зору, ви можете описати її з внутрішньої точки зору: це клас, де ви визначаєте обробку даних та управління повідомленнями, щоб дозволити реалізованій вами реальності оживати та взаємодіяти завдяки до об'єктів за допомогою екземплярів.

Отже, в UML ви реалізуєте фрактальне занурення в колеса машини і описуєте стани, взаємодії тощо, щоб мати можливість реалізувати абстрагування фрагмента реальності, з якою ви хочете працювати.

Як такий, абстрактний клас якимось чином еквівалент інтерфейсу з точки зору компілятора.

Більше інформації

Протокол (об'єктно-орієнтоване програмування)

C # - Інтерфейси

C # - Заняття


1

Дозвольте розповісти про літаючі тостери.

літаючий тостер

Звичайно, існує багато ситуацій, коли ви можете побудувати працюючу програмну систему, не оголошуючи і не застосовуючи взагалі ніяких інтерфейсів: будь-який об'єктно-орієнтований дизайн програмного забезпечення може бути реалізований за допомогою нічого, крім класів.

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

Так, буває так, що існують певні нетривіальні об'єктно-орієнтовані конструкції, які настільки простіше реалізувати, якщо використовувати інтерфейси, що інтерфейси в цих випадках практично стають необхідними.

Ці нетривіальні конструкції пов'язані з багаторазовим успадкуванням, яке у своїй "справжній" формі - це коли клас успадковує не лише один базовий клас, а два або більше базових класів. Ця справжня форма неможлива в C #, але до появи мов, таких як C # та Java, мовою, яка керувала, була C ++, яка повністю підтримує істинне множинне успадкування. На жаль, справжнє багаторазове успадкування виявилося не дуже хорошою ідеєю, оскільки воно надзвичайно ускладнює дизайн мови, а також породжує різні проблеми, наприклад знамениту «Проблему алмазів». (Див. "Яка точна проблема з багаторазовим успадкуванням?", Відповідь Дж. Френсіс )

Отже, якби хтось хотів створити клас "літаючого тостеру", він отримав би спадок від якогось існуючого класу "тостери", а також від якогось існуючого класу "літаючих". Проблема, з якою вони могли зіткнутися, полягала в тому, що джерело живлення класу тостер, можливо, був настінною розеткою, тоді як джерело живлення літаючого машинного класу, швидше за все, було їжею для голубів, і новий клас, що вийшов, або якось мати обидва, або було б незрозуміло, який би він мав. (Проблема Алмазу.)

Творці таких мов, як C # та Java, вирішили не допустити багатократного успадкування, щоб зробити мову простою та уникнути підводних каменів, як Diamond Problem. Однак деяка форма багаторазового успадкування все ще необхідна (або, принаймні, дуже бажана), тому в цих мовах вони впроваджували інтерфейси як засіб підтримки меншої форми множинного успадкування, уникаючи при цьому проблем та складності справжнього множинного успадкування.

У цій меншій формі багаторазового успадкування вам не дозволяється мати клас, який успадковує більше ніж один базовий клас, але ви можете принаймні успадковувати один або кілька інтерфейсів. Таким чином, якщо ви хочете побудувати літаючий тостер, ви не можете успадкувати як якийсь існуючий клас тостеру, так і якийсь існуючий клас польоту, але те, що ви можете зробити, це успадковувати з існуючого класу тостер, а потім також відкривати літаючий інтерфейс, який ви реалізуєте самостійно, можливо, використовуючи будь-які засоби, які ви вже успадкували від тостеру.

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


0

Інтерфейси дозволяють дизайнеру класів зробити доступні методи дуже зрозумілими для кінцевого користувача. Вони також є невід’ємною частиною поліморфізму.


Добре сказано у вашій першій заяві. Але я розумію, що ви розумієте ваше 2-е твердження, чи можете ви, будь ласка, детально розібратися з прикладом у реальному часі?
Учень

0

Я не буду публікувати визначення інтерфейсу проти абстрактного класу, тому що я думаю, що ви дуже добре знаєте теорію, і я припускаю, що ви знаєте принципи SOLID, тому давайте будемо практичними.

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

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

Тож, загалом, вам слід віддати перевагу абстрактному класу інтерфейсам, коли вам потрібно надати конструктору або будь-який код клієнту, який успадкує / розширить ваш клас


-2

Абстрактний клас розраховано на пов'язані об'єкти, де як інтерфейси можна використовувати для неспоріднених об'єктів.

Наприклад, якщо у мене є два об'єкти, які кажуть "Тварини та людина", тоді я піду на Інтерфейс, куди як би мені доводиться детально говорити: Тигр, Лев і хочу зв’язатися з Твариною, то виберу клас Анотація тварин ..

буде виглядати як нижче

   Interface             
   ____|____
  |        |
Animal   Human



  Animal (Abstract class)
   __|___
  |      |
Tiger   Lion
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.