Tolkning 1
I C# är abstrakt och virtuellt förvirrande, båda relaterade till arv, och involverar användning av överskrivning. Låt oss diskutera skillnaderna mellan de två:
1. Virtuell metod
Virtual Keyword används för att modifiera metoder i basklassen. Det finns två situationer där virtuellt används:
Scenario 1: En virtuell metod definieras i basklassen, men den virtuella metoden skrivs inte om i den härledda klassen. I anropet till den härledda klassinstansen använder den virtuella metoden metoden som definieras av basklassen.
Scenario 2: En virtuell metod definieras i basklassen och sedan skrivs metoden om med överskrivning i den härledda klassen. I anropet till den härledda klassinstansen använder den virtuella metoden den härledda omskrivningsmetoden.
2. Abstrakt metod (abstrakt metod)
Det abstrakta nyckelordet kan endast användas i abstrakta klasser för att modifiera metoder, och det finns ingen specifik implementation. Implementeringen av abstrakta metoder måste implementeras med överskrivningsnyckelordet i den härledda klassen.
Den mest väsentliga skillnaden mellan ett gränssnitt och en abstrakt klass: en abstrakt klass är en ofullständig klass, en abstraktion av ett objekt, medan ett gränssnitt är en beteendenorm.
3. Nyckelord
Statisk: När en metod deklareras som statisk är metoden en statisk metod och kompilatorn behåller implementeringen av metoden vid kompileringstillfället. Det vill säga, metoden tillhör en klass, men inte någon medlem, oavsett om en instans av klassen existerar eller inte. Precis som inmatningsfunktionen Static void Main, eftersom det är en statisk funktion, kan den kallas direkt.
Virtua: När en metod deklareras som virtuell är det en virtuell metod tills du använder variabeln ClassName = ny ClassName(); Innan en instans av en klass deklareras existerar den inte i det verkliga minnesutrymmet. Detta nyckelord används mycket ofta vid klassarv för att ge polymorfismstöd för klassmetoder.
överrrit: indikerar en omskrivning Denna klass ärver från Shape-klassen Virtuellt, abstrakt är att säga till andra klasser som vill ärva från honom att du kan åsidosätta denna metod eller egenskap hos mig, annars är det inte tillåtet. Abstrakt: Abstrakt metoddeklaration är en metod som måste överskridas av en härledd klass, som används för att ärvas; Den kan betraktas som en imaginär metod utan realisering; Om en klass innehåller en abstrakt metod måste klassen definieras som en abstrakt klass, oavsett om den innehåller andra allmänna metoder eller inte; Abstrakta klasser kan inte innehålla substanser.
a) Metoden för den virtuella modifieringen måste ha en metodimplementation (även om det bara är ett par klammer), och metoden för den abstrakta modifieringen kan inte ha en implementation.
b) virtuellt kan skrivas om av underklasser, abstrakt måste skrivas om av underklasser
c) Om en funktion i en klass modifieras genom abstakt måste även klassnamnet ändras med abstakt
d) Abstrakta modifierade klasser kan inte skapas som instanser.
e) Om en metod i C# förbereds för att skriva om föräldraklassen i underklassen måste metoden modifieras med virtual i föräldraklassen och överide i underklassen, för att undvika att programmeraren av misstag skriver om föräldrametoden för föräldraklassen i underklassen.
Observera: Klasser som modifierats med abstrakt kan endast ärvas, inte instansieras.
Tolkning 2
Både virtuell och abstrakt används för att modifiera föräldraklassen, vilket gör att barnklassen kan omdefinieras genom att överskriva definitionen av föräldraklassen.
De har en sak gemensamt: om de används för att modifiera metoder måste publik läggas till framför dem, annars uppstår kompileringsfel: virtuella eller abstrakta metoder kan inte vara privata. Trots allt tillåter tillägg av virtuell eller abstrakt att underklassen kan omdefinieras, och privata medlemmar kan inte nås av underklassen.
Men de är väldigt olika. (virtuellt är "virtuellt", abstrakt är "abstrakt").
(1) Metoden för virtuell modifiering måste implementeras (även om den bara lägger till ett par klammer), medan metoden för abstrakt modifiering inte får implementeras. Till exempel, om metoden virtuell modifiering inte är implementerad:
Fel: "Test1.fun1()" måste deklarera kroppen eftersom den inte är markerad som abstrakt, extern eller partiell
För abstrakta modifierare, om implementerade:
Fel: "Test2.fun2()" kan inte deklarera kroppen eftersom den är markerad som abstrakt
(2) virtuellt kan skrivas om av delklasser, medan abstrakt måste skrivas om av delklasser.
Det finns inget fel vid kompilering, om metoden för virtuell modifierare skrivs om måste överskrivning läggas till framför den (vilket talar om för kompilatorn att du vill skriva om den virtuella metoden), och det måste finnas en implementation, annars blir kompileringen fel:
(3) Om en klassmedlem modifieras av abstrakt måste abstrakt läggas till före klassen, eftersom endast abstrakta klasser kan ha abstrakta metoder.
(4) Instanser av abstrakta klasser kan inte skapas, de kan endast ärvas och kan inte instansieras, till exempel: BaseTest2 base2 = ny BaseTest2(); Det kommer att uppstå ett kompileringsfel: Abstrakt klass eller gränssnitt kan inte skapa en instans.
(5) I C#, om du vill skriva om en metod i en underklass, måste du lägga till virtuell före föräldrametoden och åsidosätta före underklassmetoden, för att undvika att programmerare av misstag skriver om föräldrametoden i underklassen.
(6) Den abstrakta metoden måste skrivas över, och den virtuella metoden måste ha en implementation (även om det är en metod definierad i den abstrakta klassen).
Tolkning 3 Likheter: 1. De kan alla ärvas 2. Ingen av dem kan instansieras 3. Den kan innehålla metoddeklarationer 4. Härledda klasser måste implementera orealiserade metoder Urskilja: 1. Abstrakta basklasser kan definiera fält, attribut och metodimplementationer. Gränssnitt kan endast definiera attribut, indexerare, händelser och metoddeklarationer, och kan inte innehålla fält. 2. En abstrakt klass är en ofullständig klass som behöver förfinas ytterligare, medan ett gränssnitt är en beteendenorm. Microsofts anpassade gränssnitt levereras alltid med ett kapabel fält för att bevisa att de är uttryck för "Jag kan göra det..." ” 3. Gränssnitt kan implementeras flera gånger, och abstrakta klasser kan endast ärvas av en enda person 4. Abstrakta klasser är mer definierade mellan en serie nära besläktade klasser, medan de flesta gränssnitt är löst relaterade men alla implementerar en viss funktion 5. Abstrakta klasser är begrepp abstraherade från en serie relaterade objekt, så de speglar tingens inre gemensamma egenskaper; Ett gränssnitt är en funktionell konvention definierad för att tillfredsställa externa anrop, så det speglar de yttre egenskaperna hos saker 6. Gränssnittet har i princip inga specifika ärftliga egenskaper, det lovar bara en metod som kan anropas 7. Gränssnittet kan användas för att stödja återkopplingar, men arv har inte denna funktion 8. De specifika metoder som implementeras av abstrakta klasser är virtuella som standard, men gränssnittsmetoderna i klassen som implementerar gränssnittet är icke-virtuella som standard, naturligtvis kan du också deklarera dem virtuella 9. Om den abstrakta klassen implementerar gränssnittet kan metoden i gränssnittet mappas till den abstrakta klassen som en abstrakt metod utan att behöva implementera den, men metoden i gränssnittet kan implementeras i underklassen av den abstrakta klassen Användningsregler: 1. Abstrakta klasser används främst för närbesläktade objekt, medan gränssnitt bäst används för att tillhandahålla allmän funktionalitet för irrelevanta klasser 2. Om du vill designa en stor funktionell enhet, använd abstrakta klasser; Om du vill designa små, koncisa funktionella block, använd gränssnitt. 3. Om flera versioner av komponenten förväntas skapas, skapa en abstrakt klass. När ett gränssnitt har skapats kan det inte ändras. Om en ny version av gränssnittet krävs måste ett helt nytt gränssnitt skapas. 4. Om den skapade funktionen ska användas mellan ett brett spektrum av heterogena objekt, använd gränssnittet; Om du vill erbjuda gemensam implementerad funktionalitet över alla implementationer av en komponent, använd abstrakta klasser. 5. Analysera objektet, förfina den interna gemenskapen för att bilda en abstrakt klass, som används för att uttrycka objektets essens, det vill säga "vad". Gränssnitt prioriteras när externa anrop eller funktioner behöver utökas 6. En bra gränssnittsdefinition bör vara specifik och funktionell, inte multifunktionell, annars orsakar den gränssnittsföroreningar. Om en klass endast implementerar en funktion i gränssnittet, men måste implementera andra metoder i gränssnittet, kallas det gränssnittsförorening 7. Försök undvika att använda arv för att uppnå formationsfunktionen, men använd svart box-multiplexering, det vill säga objektkombination. På grund av ökningen av antalet arvsnivåer är den mest direkta konsekvensen att när du kallar en klass i denna taxon måste du ladda in alla i stacken! Konsekvenserna kan föreställas. (Kombinerat med förståelse av stackprinciper). Samtidigt kan intresserade vänner märka att Microsoft ofta använder metoden objektkombination när de bygger en klass. Till exempel har sidklassen i asp.net egenskaper som Server Request, men i själva verket är de alla objekt för en viss klass. Att använda detta objekt i Page-klassen för att anropa metoder och egenskaper hos andra klasser är en mycket grundläggande designprincip Till exempel: Fönsterformer kan designas med abstrakta klasser, och publika operationer och egenskaper kan placeras i en abstrakt klass, så att formuläret och dialogrutan kan ärva från denna abstrakta klass och sedan expandera och förbättra efter egna behov.
Utskriftsoperationen kan tillhandahållas som ett gränssnitt till varje formulär som behöver denna funktion, eftersom innehållet i formuläret är annorlunda och de måste implementera sin egen utskriftsfunktion enligt sina egna krav. Vid utskrift anropas den endast via gränssnittet, oavsett vilket formulär som skrivs ut.
Gemensömhet, individualitet och val: Vissa böcker skriver att C# rekommenderar att använda gränssnitt istället för abstrakta basklasser, och betonar de många fördelarna med att använda gränssnitt, vilket jag inte vågar säga emot, utifrån listan ovan, finns det fortfarande många skillnader mellan de två, och förekomsten av denna skillnad måste avgöra skillnaden i tillämpliga scenarier, till exempel kan den abstrakta basklassen tillhandahålla standardimplementationer för vissa metoder, för att undvika upprepad implementering av dem i underklasser och förbättra kodens återanvändbarhet. Detta är fördelen med abstrakta klasser; Gränssnittet kan endast innehålla abstrakta metoder. När man använder abstrakta basklasser och när man använder gränssnitt beror det på hur användarna ser på kopplingarna mellan ärvda klasser, om det är personlighetsskillnader eller gemensamma kopplingar mellan dem. Låt mig illustrera med ett livsexempel.
Om du får tre objekt, nämligen människor, fiskar och grodor, och du ombeds designa en baskategori för dem för att sammanfatta kopplingen mellan dem, då kommer det första du känner vara att det finns stora skillnader mellan dem, och det är svårt att abstrahera likheterna. Här bör du överväga att använda gränssnitt istället för abstrakta basklasser av tre skäl:
1. Individualitet är större än gemenskap. 2. Personligheter med stora skillnader har några av samma beteenden. 3. Det finns stora skillnader i realiseringsmetoderna för samma beteende. Vid denna tidpunkt får du tre ytterligare objekt, nämligen crucian-karp, karp och guldfisk, och låter dig fortfarande designa basklasser för att sammanfatta kopplingen mellan dem, sedan inser du först att de alla tillhör fiskar, och det andra är att sättet de simmar på kan vara något annorlunda, så du bör använda abstrakta basklasser istället för gränssnitt, jämfört med exemplet ovan finns det tre anledningar:
1. Gemenskap är större än individualitet 2. Individer med samma gemensamma egenskaper måste ha samma egenskaper och beteenden 3. Det finns vissa skillnader i implementeringsmetoderna för samma beteende Bland flera skäl till att använda gränssnitt eller abstrakta basklasser är den tredje anledningen faktiskt densamma, som beskriver begreppet polymorfism i objektorienterat, det vill säga att det implementeras genom att skriva över föräldraklassen och anropa motsvarande metod vid körning enligt den godkända objektreferensen. Den andra anledningen börjar divergera, där gränssnitt betonar samma beteende mellan ärvda objekt, medan abstrakta klasser också betonar samma egenskaper mellan ärvda objekt. Det som verkligen skiljer gränssnitt från abstrakta basklasser är följande skäl:
Gränssnitt används när funktionell gemenskap söks mellan objekt med stora skillnader. Abstrakta basklasser används när funktionella skillnader söks mellan objekt med större gemenskap. Genom att jämföra samma och olika kan vi bara säga att gränssnitt och abstrakta klasser har sina egna styrkor, men det finns inga fördelar. I faktisk programmeringspraktik behöver vi mäta våra talanger utifrån den specifika situationen, men följande erfarenhet och ackumulering kan ge dig inspiration, utöver en del av min samling kommer många av dem från klassikerna, jag tror att de kan stå sig på prov. Så när det gäller regler och tillfällen lär vi oss dessa klassiker, det viktigaste är att tillämpa det vi har lärt oss, självklart kommer jag att vinna allas skratt med en familjs ord, fortsätt gärna.
Regler och tillfällen: 1. Kom ihåg att en av de viktigaste principerna för objektorienterat tänkande är: gränssnittsorienterad programmering. 2. Med hjälp av gränssnitt och abstrakta klasser har många idéer i de 23 designmönstren smart implementerats, och jag tror att deras kärna helt enkelt är att de är inriktade på abstrakt programmering. 3. Abstrakta klasser bör främst användas för närbesläktade objekt, medan gränssnitt bäst används för att tillhandahålla allmän funktionalitet för irrelevanta klasser. 4. Gränssnittet fokuserar på CAN-DO-relationstypen, medan den abstrakta klassen fokuserar på IS-A-relationen. 5. Beteendet hos flerdefinierade objekt i gränssnittet; abstrakta klasser multidefinierar objektens egenskaper; 6. Gränssnittsdefinitioner kan använda offentliga, skyddade, interna och privata modifierare, men nästan alla gränssnitt definieras som offentliga, så det finns inget behov av att säga mer. 7. "Gränssnittet förblir oförändrat" är en viktig faktor som bör beaktas. Därför bör nya gränssnitt läggas till när tillägg från gränssnitt läggs till, inte befintliga gränssnitt. 8. Försök designa gränssnittet till ett funktionellt block med en enda funktion, med .NET Framework som exempel, IDisposable, IDisposable, IComparable, IEquatable, IEnumerable osv. innehåller alla endast en gemensam metod. 9. Den stora bokstaven "I" framför gränssnittsnamnet är en konvention, precis som fältnamnet börjar med ett understreck, vänligen följ dessa principer. 10. I gränssnittet är alla metoder som standard publika. 11. Om versionsproblem förväntas kan du skapa en "abstrakt klass". Till exempel, om du skapar en hund, en höna och en anka, bör du överväga att abstrahera djur för att hantera saker som kan uppstå i framtiden. Att lägga till nya medlemmar i gränssnittet tvingar alla härledda klasser att modifieras och kompileras om, så versionshanteringsproblem är bäst implementerade med abstrakta klasser. 12. Icke-abstrakta klasser härledda från abstrakta klasser måste inkludera alla ärvda abstrakta metoder och faktiska implementationer av abstrakta accessorer. 13. Det nya nyckelordet kan inte användas för abstrakta klasser, och de kan inte förseglas heller, eftersom abstrakta klasser inte kan instansieras. 14. Statiska eller virtuella modifierare kan inte användas i abstrakta metoddeklarationer.
|