Интерпретация 1
В C# Abstract и Virtual са объркващи, както свързани с наследяването, така и включват използването на override. Нека обсъдим разликите между двете:
1. Виртуален метод
Виртуалната ключова дума се използва за модифициране на методи в базовия клас. Има две ситуации, в които се използва виртуално:
Сценарий 1: Виртуален метод е дефиниран в базовия клас, но виртуалният метод не се пренаписва в производния клас. При извикването на производния клас, виртуалният метод използва метода, дефиниран от базовия клас.
Сценарий 2: Виртуален метод се дефинира в базовия клас и след това методът се пренаписва чрез override в производния клас. При извикването на производния клас инстанция виртуалният метод използва производния метод за пренаписване.
2. Абстрактен метод (абстрактен метод)
Абстрактната ключова дума може да се използва само в абстрактни класове за модифициране на методи и няма специфична реализация. Имплементацията на абстрактни методи трябва да се реализира с помощта на ключовата дума override в производния клас.
Най-съществената разлика между интерфейс и абстрактен клас: абстрактният клас е непълен клас, абстракция на обект, докато интерфейсът е поведенческа норма.
3. Ключови думи
Статичен: Когато даден метод е обявен като статичен, методът е статичен и компилаторът запазва реализацията на метода по време на компилиране. Тоест, методът принадлежи на клас, но не и на който и да е член, независимо дали съществува екземпляр на класа или не. Точно както функцията за влизане Static void Main, тъй като е статична функция, тя може да се извиква директно.
Virtua: Когато даден метод е обявен като Virtual, той е виртуален метод, докато не използвате променливата ClassName = нова ClassName(); Преди да се обяви екземпляр на клас, той не съществува в реалното пространство на паметта. Тази ключова дума се използва много често при класово наследяване за осигуряване на подкрепа за полиморфизъм за класови методи.
overrride: означава пренаписване Този клас наследява от класа Shape Виртуално, абстрактно означава да кажеш на други класове, които искат да наследят от него, че можеш да презапишеш този мой метод или свойство, в противен случай не е позволено. Абстрактно: Декларацията на абстрактен метод е метод, който трябва да бъде презаписан от производен клас, който се използва за наследяване; Може да се разглежда като въображаем метод без реализация; Ако клас съдържа абстрактен метод, тогава класът трябва да бъде дефиниран като абстрактен клас, независимо дали съдържа други общи методи; Абстрактните класове не могат да имат субстанции.
а) Методът на виртуалната модификация трябва да има реализация на метод (дори ако е само двойка скоби), а методът на абстрактната модификация не може да има реализация.
б) виртуалното може да бъде пренаписано чрез подкласове, абстрактното трябва да се пренаписва чрез подкласове
в) Ако функция в клас бъде модифицирана чрез абстакт, името на класа също трябва да бъде модифицирано с абстакт
г) Абстрактни модифицирани класове не могат да бъдат създавани инстанции.
e) Ако метод в C# е готов да пренапише родителския клас в подкласа, методът трябва да бъде модифициран с virtual в родителския клас и overide в подкласа, за да се избегне случайно пренаписване на родителския метод на родителския клас в подкласа.
Забележка: Класове, модифицирани с абстрактно, могат само да се наследяват, а не да се създават.
Тълкуване 2
Както виртуален, така и абстрактен се използват за модифициране на родителския клас, позволявайки дететният клас да бъде преосмислен чрез презаписване на дефиницията на родителския клас.
Те имат едно общо нещо: ако се използват за модифициране на методи, публичните трябва да бъдат добавени пред тях, в противен случай ще има грешки при компилацията: виртуалните или абстрактните методи не могат да бъдат частни. В крайна сметка, добавянето на виртуално или абстрактно позволява преосмислянето на подкласа, а частните членове не могат да бъдат достъпвани от подкласа.
Но те са много различни. (виртуалното е "виртуално", абстрактното е "абстрактно").
(1) Методът на виртуална модификация трябва да бъде реализиран (дори ако добавя само двойка скоби), докато методът на абстрактна модификация не трябва да се прилага. Например, ако методът на виртуална модификация не е реализиран:
Грешка: "Test1.fun1()" трябва да декларира тялото, защото не е маркирано като абстрактно, външно или частично
За абстрактни модификатори, ако са реализирани:
Грешка: "Test2.fun2()" не може да декларира тялото, защото е маркирано като абстрактно
(2) виртуалното може да бъде пренаписано чрез подкласове, докато абстрактното трябва да бъде пренаписано чрез подкласове.
Няма грешка при компилиране, ако методът на виртуалния модификатор бъде пренаписан, трябва да се добави презаписване пред него (което казва на компилатора, че искате да пренапишете виртуалния метод), и трябва да има имплементация, в противен случай компилацията ще бъде грешна:
(3) Ако член на класа бъде модифициран от абстрактен, абстрактното трябва да се добави преди класа, защото само абстрактните класове могат да имат абстрактни методи.
(4) Екземпляри на абстрактни класове не могат да бъдат създадени, те могат само да се наследяват и не могат да бъдат инстанцирани, например: BaseTest2 base2 = нов BaseTest2(); Ще има грешка при компилация: Абстрактен клас или интерфейс не могат да създадат инстанция.
(5) В C#, ако искате да пренапишете метод в подклас, трябва да добавите virtual преди родителския метод и да презапишете преди подкласа, за да избегнете случайно пренаписване на родителския метод в подкласа.
(6) Абстрактният метод трябва да бъде презаписан, а виртуалният метод трябва да има имплементация (дори ако е метод, дефиниран в абстрактния клас).
Интерпретация 3 Прилики: 1. Всички могат да бъдат наследени 2. Нито един от тях не може да бъде инстанциран 3. Може да съдържа декларации на методи 4. Производните класове трябва да реализират нереализирани методи Различавам: 1. Абстрактните базови класове могат да дефинират полета, атрибути и реализации на методи. Интерфейсите могат да дефинират само атрибути, индексатори, събития и декларации на методи и не могат да съдържат полета. 2. Абстрактният клас е непълен клас, който трябва да бъде допълнително усъвършенстван, докато интерфейсът е поведенческа норма. Персонализираните интерфейси на Microsoft винаги идват с поле, което може да докаже, че са израз на "Мога да го направя..." ” 3. Интерфейсите могат да се реализират многократно, а абстрактните класове могат да бъдат наследени само от един човек 4. Абстрактните класове са по-дефинирани между серия от тясно свързани класове, докато повечето интерфейси са слабо свързани, но всички реализират определена функция 5. Абстрактните класове са понятия, абстрахирани от серия свързани обекти, така че отразяват вътрешната общност на нещата; Интерфейсът е функционална конвенция, дефинирана да удовлетворява външни повиквания, така че отразява външните характеристики на нещата 6. Интерфейсът по същество няма специфични характеристики на наследяване, той само обещава метод, който може да бъде извикан 7. Интерфейсът може да се използва за поддръжка на обратни позиви, но наследяването няма тази функция 8. Специфичните методи, реализирани от абстрактни класове, са виртуални по подразбиране, но интерфейсните методи в класа, които реализират интерфейса, по подразбиране не са виртуални, разбира се, можете да ги обявите и за виртуални 9. Ако абстрактният клас реализира интерфейса, методът в интерфейса може да бъде съпоставен с абстрактния клас като абстрактен метод без да се налага да се реализира, но методът в интерфейса може да бъде реализиран в подкласа на абстрактния клас Правила за употреба: 1. Абстрактните класове се използват основно за тясно свързани обекти, докато интерфейсите са най-добре за предоставяне на обща функционалност за нерелевантни класове 2. Ако искате да проектирате голям функционален блок, използвайте абстрактни класове; Ако искате да проектирате малки, кратки функционални блокове, използвайте интерфейси. 3. Ако се очаква да се създадат няколко версии на компонента, създайте абстрактен клас. След като интерфейсът е създаден, той не може да бъде променян. Ако е необходима нова версия на интерфейса, трябва да се създаде изцяло нов интерфейс. 4. Ако създадената функция ще се използва между широк спектър от хетерогенни обекти, използвайте интерфейса; Ако искате да предоставите обща реализирана функционалност за всички реализации на компонент, използвайте абстрактни класове. 5. Анализирайте обекта, усъвършенствайте вътрешната общност, за да формирате абстрактен клас, който се използва за изразяване на същността на обекта, тоест "какво". Интерфейсите се приоритизират, когато външни повиквания или функции трябва да бъдат разширени 6. Добрата дефиниция на интерфейса трябва да бъде специфична и функционална, а не многофункционална, в противен случай ще причини замърсяване на интерфейса. Ако клас реализира само една функция на интерфейса, но трябва да приложи други методи в интерфейса, това се нарича замърсяване на интерфейса 7. Опитайте се да избягвате използването на наследяване за постигане на функцията на формиране, но използвайте мултиплексиране в черната кутия, тоест комбиниране на обекти. Поради увеличаването на броя на нивата на наследяване, най-пряката последица е, че когато извикаш клас в този таксон, трябва да ги заредиш всички в стека! Последствията могат да се представят. (Комбинирано с разбиране на принципа на стека). В същото време заинтересованите приятели могат да забележат, че Microsoft често използва метода за комбиниране на обекти при изграждането на клас. Например, в asp.net класът Page има свойства като Server Request, но всъщност всички те са обекти от определен клас. Използването на този обект на класа Page за извикване на методите и свойствата на други класове е много основен принцип на проектиране Например: Прозоречните форми могат да бъдат проектирани с абстрактни класове, а публичните операции и свойства могат да бъдат поставени в абстрактен клас, така че формата и диалоговото окно да могат да наследят от този абстрактен клас и след това да се разширяват и подобряват според собствените си нужди.
Операцията по печат може да бъде предоставена като интерфейс към всеки формуляр, който се нуждае от тази функция, тъй като съдържанието на формуляра е различно и те трябва да реализират собствена печатна функция според собствените си изисквания. При печат се извиква само през интерфейса, независимо от формата на печата.
Общност, индивидуалност и избор: Някои книги пишат, че C# препоръчва използването на интерфейси вместо абстрактни базови класове и подчертава многобройните ползи от използването на интерфейси, с които не смея да не се съглася, но от горния списък все още има много разлики между двете, а съществуването на тази разлика трябва да определи разликата в приложимите сценарии, например в абстрактния базов клас може да осигури стандартни реализации за някои методи, за да се избегне повторната им имплементация в подкласове и да се подобри повторната употреба на кода. Това е предимството на абстрактните класове; Интерфейсът може да съдържа само абстрактни методи. Що се отнася до това кога да се използват абстрактни базови класове и кога да се използват интерфейси, това зависи от начина, по който потребителите възприемат връзките между наследените класове – дали са различия в личността или общи връзки между тях. Нека илюстрирам с един житейски пример.
Ако ти дадат три обекта – хора, риби и жаби, и те помолят да проектираш базова категория, за да обобщиш връзката между тях, първото нещо, което ще усетиш, е, че има големи разлики между тях и е трудно да се абстрахират общите черти. Тук трябва да обмислите използването на интерфейси вместо абстрактни базови класове по три причини:
1. Индивидуалността е по-голяма от общото. 2. Личностите с големи разлики имат някои от същите поведения. 3. Има големи разлики в методите за реализиране на едно и също поведение. В този момент получавате още три обекта – карач, шаран и златна рибка, и все пак ви позволяват да проектирате базови класове, за да обобщите връзката между тях, първото нещо, което осъзнавате, е, че всички те принадлежат на риби, а второто е, че начинът, по който плуват, може да е малко по-различен, затова трябва да използвате абстрактни базови класове вместо интерфейси, в сравнение с горния пример има три причини:
1. Общото е по-голямо от индивидуалността 2. Индивидите с еднакви общи черти трябва да имат същите характеристики и поведения 3. Има определени разлики в методите за прилагане на едно и също поведение Сред няколкото причини за използване на интерфейси или абстрактни базови класове, третата причина всъщност е същата, която описва концепцията за полиморфизъм в обектно-ориентирания, тоест тя се реализира чрез презаписване на родителския клас и извикване на съответния метод по време на изпълнение според предоставената препратка на обекта. Втората причина започва да се различава, като интерфейсите подчертават същото поведение между наследените обекти, докато абстрактните класове също подчертават същите свойства между наследените обекти. Това, което наистина отличава интерфейсите от абстрактните базови класове, са следните причини:
Интерфейсите се използват, когато се търси функционална общност между обекти с големи разлики. Абстрактните базови класове се използват, когато се търсят функционални различия между обекти с по-голяма обща стойност. Сравнявайки еднакви и различни, можем само да кажем, че интерфейсите и абстрактните класове имат своите силни страни, но няма никакви предимства. В реалната програмна практика трябва да измерваме талантите си според конкретната ситуация, но следващият опит и натрупване може да ви вдъхнови, освен част от моето натрупване, много от тях идват от класиката, вярвам, че могат да издържат на изпитанието. Така че в правилата и поводите, които учим тези класики, най-важното е да приложим наученото, разбира се, ще спечеля всички смеха с думите на семейството, моля, продължете.
Правила и поводи: 1. Запомнете, че един от най-важните принципи на обектно-ориентираното мислене е: интерфейсно-ориентираното програмиране. 2. С помощта на интерфейси и абстрактни класове много идеи в 23-те дизайнерски шаблона са умело реализирани и мисля, че тяхната същност е просто в това, че са ориентирани към абстрактно програмиране. 3. Абстрактните класове трябва да се използват основно за тясно свързани обекти, докато интерфейсите са най-добре за предоставяне на обща функционалност за нерелевантни класове. 4. Интерфейсът се фокусира върху типа CAN-DO връзка, докато абстрактният клас се фокусира върху IS-A връзката. 5. Поведението на многодефинирани обекти в интерфейса; абстрактните класове мултидефинират свойствата на обектите; 6. Дефинициите на интерфейси могат да използват публични, защитени, вътрешни и частни модификатори, но почти всички интерфейси са дефинирани като публични, така че няма нужда да се казва повече. 7. "Интерфейсът остава непроменен" е важен фактор, който трябва да се вземе предвид. Затова при добавяне на разширения от интерфейси трябва да се добавят нови интерфейси, а не съществуващи. 8. Опитайте да проектирате интерфейса във функционален блок с една функция, като вземете .NET Framework за пример – IDisposable, IDisposable, IComparable, IEquatable, IEnumerable и др. съдържат само един често срещан метод. 9. Главната буква "I" пред името на интерфейса е конвенция, точно както името на полето започва с подчертаване, моля, спазвайте тези принципи. 10. В интерфейса всички методи по подразбиране са публични. 11. Ако се очакват проблеми с версиите, можете да създадете "абстрактен клас". Например, ако създадете куче, кокошка и патица, трябва да обмислите абстрахиране на животни, за да се справите с неща, които може да възникнат в бъдеще. Добавянето на нови членове към интерфейса принуждава всички производни класове да бъдат модифицирани и прекомпилирани, затова проблемите с версионирането най-добре се реализират с абстрактни класове. 12. Неабстрактните класове, произтичащи от абстрактни класове, трябва да включват всички наследени абстрактни методи и реални реализации на абстрактни аксесори. 13. Новата ключова дума не може да се използва за абстрактни класове, нито може да бъде запечатана, защото абстрактните класове не могат да бъдат инстанцирани. 14. Статични или виртуални модификатори не могат да се използват при декларации на абстрактни методи.
|