Interpretare 1
În C#, Abstract și Virtual sunt confuze, ambele legate de moștenire și implică utilizarea suprascrierii. Să discutăm diferențele dintre cele două:
1. Metoda virtuală
cuvântul cheie virtual este folosit pentru a modifica metodele din clasa de bază. Există două situații în care se folosește virtualul:
Scenariul 1: O metodă virtuală este definită în clasa de bază, dar metoda virtuală nu este rescrisă în clasa derivată. În apelul către instanța clasei derivate, metoda virtuală folosește metoda definită de clasa de bază.
Scenariul 2: O metodă virtuală este definită în clasa de bază, apoi metoda este rescrisă folosind suprascrierea în clasa derivată. În apelul către instanța clasei derivate, metoda virtuală folosește metoda de rescriere derivată.
2. Metodă abstractă (metodă abstractă)
Cuvântul cheie abstract poate fi folosit doar în clasele abstracte pentru a modifica metodele, iar nu există o implementare specifică. Implementarea metodelor abstracte trebuie implementată folosind cuvântul cheie de suprascriere din clasa derivată.
Cea mai esențială diferență dintre o interfață și o clasă abstractă: o clasă abstractă este o clasă incompletă, o abstractizare a unui obiect, în timp ce o interfață este o normă comportamentală.
3. Cuvinte cheie
Static: Când o metodă este declarată ca Statică, metoda este o metodă statică, iar compilatorul păstrează implementarea metodei la compilare. Adică, metoda aparține unei clase, dar nu niciunui membru, indiferent dacă există sau nu o instanță a clasei. La fel ca funcția de intrare Static void Main, pentru că este o funcție statică, poate fi numită direct.
Virtua: Când o metodă este declarată ca Virtuală, este o metodă virtuală până când folosești variabila ClassName = new ClassName(); Înainte de a declara o instanță a unei clase, aceasta nu există în spațiul real de memorie. Acest cuvânt-cheie este foarte des folosit în moștenirea claselor pentru a oferi suport pentru polimorfisme pentru metodele de clasă.
override: indică o rescriere Această clasă moștenește de la clasa Shape Virtual, abstract înseamnă să le spui altor clase care vor să moștenească de la el că poți suprascrie această metodă sau proprietate a mea, altfel nu este permis. Rezumat: Declararea metodei abstracte este o metodă care trebuie suprascrisă de o clasă derivată, care este folosită pentru a fi moștenită; Poate fi privită ca o metodă imaginară fără realizare; Dacă o clasă conține o metodă abstractă, atunci clasa trebuie definită ca o clasă abstractă, indiferent dacă conține sau nu alte metode generale; Clasele abstracte nu pot conține substanțe.
a) Metoda modificării virtuale trebuie să aibă o implementare a metodei (chiar dacă este doar o pereche de abrazatoare), iar metoda modificării abstracte nu poate avea o implementare.
b) virtualul poate fi rescris de subclase, abstractul trebuie rescris de subclase
c) Dacă o funcție dintr-o clasă este modificată prin abstact, numele clasei trebuie de asemenea modificat cu abstact
d) Clasele abstracte modificate nu pot fi create instanțe.
e) Dacă o metodă din C# este pregătită să rescrie clasa părinte în subclasă, metoda trebuie modificată cu virtual în clasa părinte și suprapuse în subclasă, evitând ca programatorul să rescrie accidental metoda părinte a clasei părinte în subclasă.
Notă: Clasele modificate cu abstract pot fi doar moștenite, nu instanțiate.
Interpretarea 2
Atât virtual, cât și abstract sunt folosite pentru a modifica clasa părinte, permițând redefinirea clasei copil prin suprascrierea definiției clasei părinte.
Au un lucru în comun: dacă sunt folosite pentru a modifica metodele, public trebuie adăugat în fața lor, altfel vor apărea erori de compilare: metodele virtuale sau metodele abstracte nu pot fi private. La urma urmei, adăugarea virtualului sau abstractului permite redefinirea subclasei, iar membrii privați nu pot fi accesați de subclasă.
Dar sunt foarte diferite. (virtual este "virtual", abstract este "abstract").
(1) Metoda modificării virtuale trebuie implementată (chiar dacă adaugă doar o pereche de abrazatoare), în timp ce metoda modificării abstracte nu trebuie implementată. De exemplu, dacă metoda de modificare virtuală nu este implementată:
Eroare: "Test1.fun1()" trebuie să declare corpul deoarece nu este marcat ca abstract, extern sau parțial
Pentru modificatorii abstracti, dacă sunt implementați:
Eroare: "Test2.fun2()" nu poate declara corpul deoarece este marcat ca abstract
(2) virtualul poate fi rescris prin subclase, în timp ce abstractul trebuie rescris de subclase.
Nu există eroare la compilare, dacă metoda modificatorului virtual este rescrisă, trebuie adăugată suprascrierea în fața acesteia (care îi spune compilatorului că doriți să rescrieți metoda virtuală), iar trebuie să existe o implementare, altfel compilarea va fi greșită:
(3) Dacă un membru al clasei este modificat de abstract, abstract trebuie adăugat înaintea clasei, deoarece doar clasele abstracte pot avea metode abstracte.
(4) Instanțele claselor abstracte nu pot fi create, ele pot fi doar moștenite și nu pot fi instanțiate, de exemplu: BaseTest2 base2 = noul BaseTest2(); Va exista o eroare de compilare: Clasa abstractă sau interfața nu poate crea o instanță.
(5) În C#, dacă vrei să rescrii o metodă într-o subclasă, trebuie să adaugi virtual înaintea metodei părinte și să suprascrii înainte de metoda subclasei, pentru a evita ca programatorii să rescrie accidental metoda părinte în subclasă.
(6) Metoda abstractă trebuie suprascrisă, iar metoda virtuală trebuie să aibă o implementare (chiar dacă este o metodă definită în clasa abstractă).
Interpretarea 3 Asemănări: 1. Toate pot fi moștenite 2. Niciuna dintre ele nu poate fi instanțiată 3. Poate conține declarații de metodă 4. Clasele derivate trebuie să implementeze metode nerealizate Deosebi: 1. Clasele de bază abstracte pot defini câmpuri, atribute și implementări de metode. Interfețele pot defini doar atribute, indexatori, evenimente și declarații de metodă și nu pot conține câmpuri. 2. O clasă abstractă este o clasă incompletă care trebuie rafinată suplimentar, în timp ce o interfață este o normă comportamentală. Interfețele personalizate Microsoft vin întotdeauna cu un câmp capabil să demonstreze că sunt expresii ale expresiei "Pot să o fac..." ” 3. Interfețele pot fi implementate de mai multe ori, iar clasele abstracte pot fi moștenite doar de o singură persoană 4. Clasele abstracte sunt mai bine definite între o serie de clase strâns înrudite, în timp ce majoritatea interfețelor sunt vag legate, dar toate implementează o anumită funcție 5. Clasele abstracte sunt concepte abstractizate dintr-o serie de obiecte înrudite, astfel încât reflectă comunitatea internă a lucrurilor; O interfață este o convenție funcțională definită pentru a satisface apelurile externe, deci reflectă caracteristicile externe ale lucrurilor 6. Interfața practic nu are caracteristici specifice de moștenire, promite doar o metodă care poate fi numită 7. Interfața poate fi folosită pentru a suporta callback-uri, dar moștenirea nu are această funcție 8. Metodele specifice implementate de clasele abstracte sunt virtuale implicit, dar metodele de interfață din clasa care implementează interfața sunt nevirtuale implicit, desigur, le poți declara virtuale 9. Dacă clasa abstractă implementează interfața, metoda din interfață poate fi mapată la clasa abstractă ca metodă abstractă fără a fi nevoie să o implementeze, dar metoda din interfață poate fi implementată în subclasa clasei abstracte Reguli de utilizare: 1. Clasele abstracte sunt folosite în principal pentru obiecte strâns înrudite, în timp ce interfețele sunt cel mai bine folosite pentru a oferi funcționalitate generală pentru clasele irelevante 2. Dacă vrei să proiectezi o unitate funcțională mare, folosește clase abstracte; Dacă vrei să proiectezi blocuri funcționale mici și concise, folosește interfețe. 3. Dacă se așteaptă să fie create mai multe versiuni ale componentei, se creează o clasă abstractă. Odată ce o interfață este creată, aceasta nu poate fi modificată. Dacă este necesară o nouă versiune a interfeței, trebuie creată o interfață complet nouă. 4. Dacă funcția creată va fi folosită între o gamă largă de obiecte eterogene, se folosește interfața; Dacă vrei să oferi funcționalitate implementată comună în toate implementările unei componente, folosește clase abstracte. 5. Analizează obiectul, rafinează comunalitatea internă pentru a forma o clasă abstractă, care este folosită pentru a exprima esența obiectului, adică "ce". Interfețele sunt prioritizate atunci când apelurile sau funcțiile externe trebuie extinse 6. O definiție bună a interfeței trebuie să fie specifică și funcțională, nu multifuncțională, altfel va cauza poluare a interfeței. Dacă o clasă implementează doar o singură funcție a interfeței, dar trebuie să implementeze alte metode în interfață, aceasta se numește poluare a interfeței 7. Încearcă să eviți folosirea moștenirii pentru a obține funcția de formare, dar folosește multiplexarea cutiei negre, adică combinația de obiecte. Din cauza creșterii nivelurilor de moștenire, cea mai directă consecință este că atunci când chemi o clasă în acest taxon, trebuie să le încarci pe toate în stivă! Consecințele pot fi imaginate. (Combinat cu înțelegerea principiului stack-ului). În același timp, prietenii interesați pot observa că Microsoft folosește adesea metoda combinării obiectelor atunci când construiește o clasă. De exemplu, în asp.net, clasa Page are proprietăți precum Server Request, dar de fapt toate sunt obiecte ale unei anumite clase. Folosirea acestui obiect al clasei Page pentru a chema metodele și proprietățile altor clase este un principiu de proiectare foarte de bază De exemplu: Formularele ferestrelor pot fi proiectate cu clase abstracte, iar operațiunile și proprietățile publice pot fi plasate într-o clasă abstractă, astfel încât formularul și caseta de dialog să moștenească din această clasă abstractă și apoi să se extindă și să se îmbunătățească în funcție de propriile nevoi.
Operațiunea de imprimare poate fi oferită ca o interfață pentru fiecare formular care are nevoie de această funcție, deoarece conținutul formularului este diferit și trebuie să implementeze propria funcție de imprimare conform propriilor cerințe. La imprimare, este apelată doar prin interfață, indiferent de formularul imprimat.
Comunalitate, individualitate și alegere: Unele cărți scriu că C# recomandă folosirea interfețelor în locul claselor de bază abstracte și subliniază numeroasele beneficii ale utilizării interfețelor, cu care nu îndrăznesc să contest, din lista de mai sus există încă multe diferențe între cele două, iar existența acestei diferențe trebuie să determine diferența în scenariile aplicabile, de exemplu, în clasa de bază abstractă poate oferi implementări implicite pentru unele metode, pentru a evita implementările repetate în subclase și a îmbunătăți reutilizarea codului. Acesta este avantajul claselor abstracte; Interfața poate conține doar metode abstracte. În ceea ce privește momentul folosirii claselor de bază abstracte și a interfețelor, depinde de modul în care utilizatorii percep conexiunile dintre clasele moștenite, dacă acestea sunt diferențe de personalitate sau conexiuni comune între ele. Permiteți-mi să ilustrez cu un exemplu de viață.
Dacă ți se dau trei obiecte, și anume oameni, pești și broaște, și ți se cere să proiectezi o categorie de bază pentru ca ele să rezume legătura dintre ele, atunci primul lucru pe care îl vei simți este că există diferențe mari între ele și este dificil să abstractizezi punctele comune. Aici ar trebui să iei în considerare folosirea interfețelor în locul claselor de bază abstracte din trei motive:
1. Individualitatea este mai mare decât comunalitatea. 2. Personalitățile cu diferențe mari au unele dintre aceleași comportamente. 3. Există diferențe mari în metodele de realizare a aceluiași comportament. În acest moment, primești încă trei obiecte, și anume crap crucian, crap și peștișor auriu, și totuși poți proiecta clase de bază pentru a rezuma legătura dintre ele, apoi primul lucru pe care îl realizezi este că toate aparțin peștilor, iar al doilea este că modul în care înoată poate fi ușor diferit, așa că ar trebui să folosești clase de bază abstracte în loc de interfețe, comparativ cu exemplul de mai sus, există trei motive:
1. Comunitatea este mai mare decât individualitatea 2. Indivizii cu aceleași elemente comune trebuie să aibă aceleași atribute și comportamente 3. Există anumite diferențe în metodele de implementare ale aceluiași comportament Dintre numeroasele motive pentru utilizarea interfețelor sau claselor de bază abstracte, al treilea motiv este de fapt același, care descrie conceptul de polimorfism în orientarea pe obiect, adică este implementată prin suprascrierea clasei părinte și apelarea metodei corespunzătoare la rulare în funcție de referința la obiect transmisă. Al doilea motiv începe să se divergă, interfețele accentuând același comportament între obiectele moștenite, în timp ce clasele abstracte accentuează aceleași proprietăți între obiectele moștenite. Ceea ce diferențiază cu adevărat interfețele de clasele de bază abstracte sunt următoarele motive:
Interfețele sunt folosite atunci când se caută comunalitate funcțională între obiecte cu diferențe mari. Clasele de bază abstracte sunt folosite atunci când se caută diferențe funcționale între obiecte cu mai multe elemente comune. Comparând aceleași și diferitele, putem spune doar că interfețele și clasele abstracte au propriile puncte forte, dar nu există avantaje. În practica efectivă a programării, trebuie să ne măsurăm talentele în funcție de situația specifică, dar experiența și acumularea următoare îți pot oferi inspirație, pe lângă unele dintre acumulările mele, multe dintre ele provin din clasice, cred că pot rezista testului. Așadar, în reguli și ocazii, învățăm aceste clasice, cel mai important este să aplicăm ceea ce am învățat, desigur, voi câștiga râsul tuturor cu cuvintele unei familii, vă rog să continuați.
Reguli și ocazii: 1. Amintește-ți că unul dintre cele mai importante principii ale gândirii orientate pe obiecte este: programarea orientată pe interfețe. 2. Cu ajutorul interfețelor și al claselor abstracte, multe idei din cele 23 de modele de design au fost implementate inteligent, iar esența lor este pur și simplu că sunt orientate spre programarea abstractă. 3. Clasele abstracte ar trebui folosite în principal pentru obiecte strâns înrudite, în timp ce interfețele sunt cel mai bine folosite pentru a oferi funcționalitate generală pentru clasele irelevante. 4. Interfața se concentrează pe tipul de relație CAN-DO, în timp ce clasa abstractă se concentrează pe relația IS-A. 5. Comportamentul obiectelor multi-definite în interfață; clasele abstracte definesc mai multe proprietăți ale obiectelor; 6. Definițiile interfețelor pot folosi modificatori publici, protejați, interni și privați, dar aproape toate interfețele sunt definite ca publice, deci nu este nevoie să se spună mai mult. 7. "Interfața rămâne neschimbată" este un factor important care trebuie luat în considerare. Prin urmare, atunci când se adaugă extensii din interfețe, ar trebui adăugate interfețe noi, nu interfețe existente. 8. Încearcă să proiectezi interfața într-un bloc funcțional cu o singură funcție, luând ca exemplu .NET Framework, IDisposable, IDisposable, IComparable, IEquatable, IEnumerable etc. conțin toate o singură metodă comună. 9. Litera mare "I" din fața numelui interfeței este o convenție, la fel cum numele câmpului începe cu un subliniu, vă rugăm să respectați aceste principii. 10. În interfață, toate metodele sunt implicite publice. 11. Dacă sunt așteptate probleme de versiune, poți crea o "clasă abstractă". De exemplu, dacă creezi un câine, o găină și o rață, ar trebui să iei în considerare abstractizarea animalelor pentru a face față situațiilor care ar putea apărea în viitor. Adăugarea de membri noi în interfață forțează modificarea și recompilarea tuturor claselor derivate, astfel încât problemele de versionare sunt cel mai bine implementate cu clase abstracte. 12. Clasele non-abstracte derivate din clase abstracte trebuie să includă toate metodele abstracte moștenite și implementările reale ale accesorilor abstracti. 13. Noul cuvânt-cheie nu poate fi folosit pentru clasele abstracte, nici nu pot fi sigilate, deoarece clasele abstracte nu pot fi instanțiate. 14. Modificatorii statici sau virtuali nu pot fi folosiți în declarațiile metodelor abstracte.
|