Dit artikel is een spiegelartikel van machinevertaling, klik hier om naar het oorspronkelijke artikel te gaan.

Bekijken: 18805|Antwoord: 0

[Communicatie] De overeenkomsten en verschillen tussen virtuele en (abstracte) abstracte en interface in C#...

[Link kopiëren]
Geplaatst op 22-04-2019 14:41:09 | | |
Interpretatie 1

In C# zijn abstract en virtueel verwarrend, beide gerelateerd aan overerving, en vereisen ze het gebruik van override. Laten we de verschillen tussen de twee bespreken:

1. Virtuele methode

virtueel trefwoord wordt gebruikt om methoden in de basisklasse aan te passen. Er zijn twee situaties waarin virtueel wordt gebruikt:

Scenario 1: Een virtuele methode wordt gedefinieerd in de basisklasse, maar de virtuele methode wordt niet herschreven in de afgeleide klasse. In de aanroep van de afgeleide klasse-instantie gebruikt de virtuele methode de methode die door de basisklasse is gedefinieerd.

Scenario 2: Een virtuele methode wordt gedefinieerd in de basisklasse en vervolgens wordt de methode herschreven met override in de afgeleide klasse. In de aanroep van de afgeleide klasse-instantie gebruikt de virtuele methode de afgeleide herschrijfmethode.

2. Abstracte methode (abstracte methode)

Het abstracte trefwoord kan alleen in abstracte klassen worden gebruikt om methoden aan te passen, en er is geen specifieke implementatie. De implementatie van abstracte methoden moet worden uitgevoerd met het override-sleutelwoord in de afgeleide klasse.

Het belangrijkste verschil tussen een interface en een abstracte klasse: een abstracte klasse is een onvolledige klasse, een abstractie van een object, terwijl een interface een gedragsnorm is.


3. Trefwoorden

Statisch: Wanneer een methode als statisch wordt gedeclareerd, is de methode een statische methode en houdt de compiler de implementatie van de methode bij het compileren bij. Dat wil zeggen, de methode behoort tot een klasse, maar niet tot een lid, ongeacht of er een instantie van de klasse bestaat of niet. Net als de invoerfunctie Static void Main, kan deze vanwege het feit dat het een statische functie is, direct worden genoemd.

Virtua: Wanneer een methode als Virtueel wordt gedeclareerd, is het een virtuele methode totdat je de variabele ClassName = nieuwe ClassName() gebruikt; Voordat een instantie van een klasse wordt gedeclareerd, bestaat deze niet in de echte geheugenruimte. Dit trefwoord wordt zeer vaak gebruikt bij klasse-overerving om polymorfisme-ondersteuning te bieden voor klassemethoden.

overrride: geeft een herschrijving aan Deze klasse erft van de Shape-klasse
Virtueel, abstract is om andere klassen die van hem willen erven te vertellen dat je deze methode of eigenschap van mij kunt overschrijven, anders is het niet toegestaan.
Abstract Methode-declaratie is een methode die moet worden overschreven door een afgeleide klasse, die wordt gebruikt om te worden geërfd; Het kan worden beschouwd als een imaginaire methode zonder realisatie; Als een klasse een abstracte methode bevat, dan moet de klasse worden gedefinieerd als een abstracte klasse, ongeacht of deze andere algemene methoden bevat of niet; Abstracte klassen kunnen geen substanties hebben.

a) De methode van de virtuele modificatie moet een methode-implementatie hebben (zelfs als het slechts een paar beugels is), en de methode van de abstracte modificatie kan geen implementatie hebben.

b) virtueel kan worden herschreven door subklassen, abstract moet worden herschreven door subklassen

c) Als een functie in een klasse door abstact wordt gewijzigd, moet de klassenaam ook met abstact worden aangepast

d) Abstract aangepaste klassen kunnen geen instanties worden aangemaakt.

e) Als een methode in C# wordt voorbereid om de ouderklasse in de subklasse te herschrijven, moet de methode worden aangepast met virtual in de ouderklasse en overide in de subklasse, zodat de programmeur per ongeluk de oudermethode van de ouderklasse in de subklasse herschrijft.

Opmerking: Klassen die met abstract zijn aangepast kunnen alleen worden geërfd, niet geïnstantieerd.

Interpretatie 2

Zowel virtueel als abstract worden gebruikt om de ouderklasse te wijzigen, waardoor de kindklasse opnieuw kan worden gedefinieerd door de definitie van de ouderklasse te overschrijven.

Ze hebben één ding gemeen: als ze worden gebruikt om methoden te wijzigen, moet er publiek voor worden toegevoegd, anders ontstaan er compilatiefouten: virtuele methoden of abstracte methoden kunnen niet privé zijn. Het toevoegen van virtueel of abstract maakt het immers mogelijk om de subklasse opnieuw te definiëren, en kunnen private leden niet worden benaderd door de subklasse.

Maar ze zijn heel verschillend. (Virtueel is "virtueel", abstract is "abstract").

(1) De methode van virtuele modificatie moet worden geïmplementeerd (zelfs als er slechts een paar beugels worden toegevoegd), terwijl de methode van abstracte modificatie niet mag worden toegepast. Bijvoorbeeld, als de methode van virtuele modificatie niet is geïmplementeerd:

Fout: "Test1.fun1()" moet het lichaam declareren omdat het niet als abstract, extern of parteel is gemarkeerd   

Voor abstracte modifiers, indien geïmplementeerd:


Fout: "Test2.fun2()" kan het lichaam niet declareren omdat het als abstract is gemarkeerd   

(2) virtueel kan worden herschreven door subklassen, terwijl abstract door subklassen moet worden herschreven.
Er is geen fout bij het compileren als de methode van de virtuele modifier wordt herschreven, moet override ervoor worden toegevoegd (wat de compiler aangeeft dat je de virtuele methode wilt herschrijven), en er moet een implementatie zijn, anders is de compilatie fout:
(3) Als een klasselid wordt gewijzigd door abstract, moet abstract vóór de klasse worden toegevoegd, omdat alleen abstracte klassen abstracte methoden kunnen hebben.

(4) Instanties van abstracte klassen kunnen niet worden aangemaakt, ze kunnen alleen worden geërfd en niet worden geïnstantieerd, bijvoorbeeld: BaseTest2 base2 = nieuwe BaseTest2(); Er zal een compilatiefout zijn: Abstracte klasse of interface kan geen instantie aanmaken.

(5) In C#, als je een methode in een subklasse wilt herschrijven, moet je virtual toevoegen vóór de oudermethode en overschrijven vóór de subclass-methode, om te voorkomen dat programmeurs per ongeluk de oudermethode in de subklasse herschrijven.

(6) De abstracte methode moet worden overschreven, en de virtuele methode moet een implementatie hebben (zelfs als het een methode is die in de abstracte klasse is gedefinieerd).
Interpretatie 3
Overeenkomsten:
1. Ze kunnen allemaal geërfd worden
2. Geen van hen kan worden geïnstantieerd
3. Het kan methodeverklaringen bevatten
4. Afgeleide klassen moeten niet-gerealiseerde methoden implementeren
Onderscheiden:
1. Abstracte basisklassen kunnen velden, attributen en methode-implementaties definiëren. Interfaces kunnen alleen attributen, indexers, gebeurtenissen en methodeverklaringen definiëren en kunnen geen velden bevatten.
2. Een abstracte klasse is een onvolledige klasse die verder verfijnd moet worden, terwijl een interface een gedragsnorm is. Microsofts aangepaste interfaces worden altijd geleverd met een geschikt veld om te bewijzen dat ze uitingen zijn van de "Ik kan het..." ”
3. Interfaces kunnen meerdere keren worden geïmplementeerd, en abstracte klassen kunnen slechts door één persoon worden geërfd
4. Abstracte klassen zijn meer gedefinieerd tussen een reeks nauw verwante klassen, terwijl de meeste interfaces losjes verwant zijn maar allemaal een bepaalde functie implementeren
5. Abstracte klassen zijn concepten die zijn geabstraheerd uit een reeks verwante objecten, zodat ze de interne gemeenschappelijkheid van dingen weerspiegelen; Een interface is een functionele conventie die is gedefinieerd om externe aanroepen te voldoen, dus het weerspiegelt de externe kenmerken van dingen
6. De interface heeft in feite geen specifieke kenmerken van overerving, het belooft alleen een methode die kan worden aangeroepen
7. De interface kan worden gebruikt om callbacks te ondersteunen, maar overerving heeft deze functie niet
8. De specifieke methoden die door abstracte klassen worden geïmplementeerd zijn standaard virtueel, maar de interfacemethoden in de klasse die de interface implementeren zijn standaard niet-virtueel; natuurlijk kun je ze ook virtueel verklaren
9. Als de abstracte klasse de interface implementeert, kan de methode in de interface worden toegewezen aan de abstracte klasse als een abstracte methode zonder dat deze geïmplementeerd hoeft te worden, maar de methode in de interface kan worden geïmplementeerd in de subklasse van de abstracte klasse
Gebruiksregels:
1. Abstracte klassen worden voornamelijk gebruikt voor nauw verwante objecten, terwijl interfaces het beste worden gebruikt om algemene functionaliteit te bieden voor irrelevante klassen
2. Als je een grote functionele eenheid wilt ontwerpen, gebruik dan abstracte klassen; Als je kleine, beknopte functionele blokken wilt ontwerpen, gebruik dan interfaces.
3. Als er meerdere versies van de component worden verwacht, maak dan een abstracte klasse aan. Zodra een interface is gemaakt, kan deze niet meer worden gewijzigd. Als een nieuwe versie van de interface nodig is, moet er een volledig nieuwe interface worden gemaakt.
4. Als de gecreëerde functie gebruikt zal worden tussen een breed scala aan heterogene objecten, gebruik dan de interface; Als je gemeenschappelijke geïmplementeerde functionaliteit wilt bieden voor alle implementaties van een component, gebruik dan abstracte klassen.
5. Analyseer het object, verfijn de interne gemeenschappelijkheid om een abstracte klasse te vormen, die wordt gebruikt om de essentie van het object uit te drukken, dat wil zeggen: "wat". Interfaces krijgen prioriteit wanneer externe aanroepen of functies moeten worden uitgebreid
6. Een goede interfacedefinitie moet specifiek en functioneel zijn, niet multifunctioneel, anders veroorzaakt het interfacevervuiling. Als een klasse slechts één functie van de interface implementeert, maar andere methoden in de interface moet implementeren, wordt dit interface-pollution genoemd
7. Probeer overerving te vermijden om de formatiefunctie te bereiken, maar gebruik black box multiplexing, dat wil zeggen objectcombinaties. Door de toename van het aantal erfniveaus is het meest directe gevolg dat wanneer je een klasse in dit taxon aanroept, je ze allemaal in de stack moet laden! De gevolgen zijn voorstellend. (In combinatie met begrip van stackprincipes). Tegelijkertijd merken geïnteresseerde vrienden dat Microsoft vaak de methode van objectcombinatie gebruikt bij het bouwen van een klasse. Bijvoorbeeld, in asp.net heeft de Page-klasse eigenschappen zoals Server Request, maar in feite zijn het allemaal objecten van een bepaalde klasse. Het gebruik van dit object van de Page-klasse om de methoden en eigenschappen van andere klassen aan te roepen is een zeer basaal ontwerpprincipe
Bijvoorbeeld:
Venstervormen kunnen worden ontworpen met abstracte klassen, en publieke bewerkingen en eigenschappen kunnen in een abstracte klasse worden geplaatst, zodat het formulier en het dialoogvenster van deze abstracte klasse kunnen erven, en vervolgens kunnen uitbreiden en verbeteren naar eigen behoeften.

De afdrukoperatie kan worden aangeboden als interface voor elk formulier dat deze functie nodig heeft, omdat de inhoud van het formulier anders is en ze hun eigen printfunctie moeten implementeren volgens hun eigen eisen. Bij het afdrukken wordt het alleen via de interface aangeroepen, ongeacht welke vorm wordt afgedrukt.

Gemeenschappelijkheid, Individualiteit en Keuze:
Sommige boeken schrijven dat C# aanbeveelt interfaces te gebruiken in plaats van abstracte basisklassen, en benadrukken de vele voordelen van het gebruik van interfaces, waar ik het niet mee eens ben; uit bovenstaande lijst zijn er nog steeds veel verschillen tussen de twee, en het bestaan van dit verschil moet het verschil bepalen in toepasselijke scenario's, bijvoorbeeld in de abstracte basisklasse kan standaardimplementaties voor sommige methoden worden geleverd, om herhaalde implementaties ervan in subklassen te voorkomen en de herbruikbaarheid van code te verbeteren. Dit is het voordeel van abstracte klassen; De interface kan alleen abstracte methoden bevatten. Wat betreft wanneer abstracte basisklassen en wanneer interfaces gebruikt moeten worden, hangt het af van hoe gebruikers de verbindingen tussen geërfde klassen zien, of het nu persoonlijkheidsverschillen zijn of veelvoorkomende verbindingen tussen deze klassen. Laat me het illustreren met een levensvoorbeeld.

Als je drie objecten krijgt, namelijk mensen, vissen en kikkers, en je wordt gevraagd een basiscategorie voor hen te ontwerpen om de verbinding tussen hen samen te vatten, dan zul je als eerste voelen dat er grote verschillen tussen hen zijn, en het moeilijk is om de overeenkomsten te abstraheren. Hier zou je interfaces moeten overwegen in plaats van abstracte basisklassen om drie redenen:
1. Individualiteit is belangrijker dan gemeenschappelijkheid.
2. Persoonlijkheden met grote verschillen vertonen enkele van dezelfde gedragingen.
3. Er zijn grote verschillen in de realisatiemethoden van hetzelfde gedrag.
Op dit moment krijg je nog drie objecten, namelijk kruiskarper, karper en goudvis, en kun je nog steeds basisklassen ontwerpen om de verbinding tussen hen samen te vatten, dan realiseer je je dat ze allemaal bij vissen horen, en ten tweede kan de manier waarop ze zwemmen iets anders zijn, dus je zou abstracte basisklassen moeten gebruiken in plaats van interfaces; vergeleken met het bovenstaande voorbeeld zijn er drie redenen:
1. Gemeenschappelijkheid is groter dan individualiteit
2. Individuen met dezelfde gemeenschappelijkheid moeten dezelfde eigenschappen en gedragingen hebben
3. Er zijn bepaalde verschillen in de implementatiemethoden van hetzelfde gedrag
Van de verschillende redenen om interfaces of abstracte basisklassen te gebruiken, is de derde reden eigenlijk dezelfde, namelijk het concept van polymorfisme in objectgeoriënteerd, dat wil zeggen dat het wordt geïmplementeerd door de ouderklasse te overschrijven en de bijbehorende methode tijdens runtime aan te roepen volgens de doorgegeven objectreferentie. De tweede reden begint te divergeren, waarbij interfaces hetzelfde gedrag tussen geërfde objecten benadrukken, terwijl abstracte klassen ook dezelfde eigenschappen tussen geërfde objecten benadrukken. Wat interfaces echt onderscheidt van abstracte basisklassen zijn de volgende redenen:

Interfaces worden gebruikt wanneer functionele gemeenschappelijkheid wordt gezocht tussen objecten met grote verschillen.
Abstracte basisklassen worden gebruikt wanneer functionele verschillen worden gezocht tussen objecten met meer gemeenschappelijkheid.
Door hetzelfde en verschillend te vergelijken, kunnen we alleen zeggen dat interfaces en abstracte klassen hun eigen sterke punten hebben, maar dat er geen voordelen zijn. In de daadwerkelijke programmeerpraktijk moeten we onze talenten meten aan de hand van de specifieke situatie, maar de volgende ervaring en verzameling kunnen je inspireren; naast een deel van mijn verzameling komen velen uit de klassiekers, ik geloof dat ze de test kunnen doorstaan. Dus bij de regels en gelegenheden leren we deze klassiekers, het belangrijkste is om toe te passen wat we geleerd hebben, natuurlijk zal ik ieders lach winnen met de woorden van een familie, ga alsjeblieft door.

Regels en gelegenheden:
1. Onthoud dat een van de belangrijkste principes van objectgeoriënteerd denken is: interface-georiënteerd programmeren.
2. Met behulp van interfaces en abstracte klassen zijn veel ideeën in de 23 ontwerppatronen slim geïmplementeerd, en ik denk dat hun essentie simpelweg is dat ze gericht zijn op abstract programmeren.
3. Abstracte klassen moeten vooral worden gebruikt voor nauw verwante objecten, terwijl interfaces het beste worden ingezet om algemene functionaliteit te bieden voor irrelevante klassen.
4. De interface richt zich op het CAN-DO-relatietype, terwijl de abstracte les zich richt op de IS-A-relatie.
5. Het gedrag van multi-defined objecten in de interface; abstracte klassen multidefiniëren de eigenschappen van objecten;
6. Interfacedefinities kunnen gebruikmaken van publieke, beschermde, interne en private modificatoren, maar bijna alle interfaces zijn als publiek gedefinieerd, dus er is geen reden om meer te zeggen.
7. "De interface blijft ongewijzigd" is een belangrijke factor die in overweging moet worden genomen. Daarom moeten bij het toevoegen van extensies van interfaces nieuwe interfaces worden toegevoegd, niet bestaande interfaces.
8. Probeer de interface te ontwerpen als een functioneel blok met één enkele functie, met .NET Framework als voorbeeld, IDisposable, IDisposable, IComparable, IEquatable, IEnumerable, enzovoort, die allemaal slechts één gemeenschappelijke methode bevatten.
9. De hoofdletter "I" voor de interfacenaam is een conventie, net zoals de veldnaam begint met een onderstreep, houd u alstublieft aan deze principes.
10. In de interface staan alle methoden standaard op publiek.
11. Als er versieproblemen worden verwacht, kun je een "abstracte klasse" aanmaken. Als je bijvoorbeeld een hond, een kip en een eend maakt, moet je overwegen dieren te abstraheren om met dingen om te gaan die in de toekomst kunnen ontstaan. Het toevoegen van nieuwe leden aan de interface dwingt alle afgeleide klassen om te worden aangepast en opnieuw gecompileerd, dus versieproblemen worden het beste geïmplementeerd met abstracte klassen.
12. Niet-abstracte klassen afgeleid van abstracte klassen moeten alle geërfde abstracte methoden en daadwerkelijke implementaties van abstracte accessors bevatten.
13. Het nieuwe trefwoord kan niet worden gebruikt voor abstracte klassen, noch kunnen ze worden verzegeld, omdat abstracte klassen niet kunnen worden geïnstantieerd.
14. Statische of virtuele modificatoren mogen niet worden gebruikt in abstracte methodeverklaringen.





Vorig:C# Enum Simple Permission Design gebruikt de eigenschap FlagsAttribute
Volgend:Het Yiyun-klaslokaal van Huang Yong heeft een nul-gebaseerd begrip van het WeChat mini-programma
Disclaimer:
Alle software, programmeermaterialen of artikelen die door Code Farmer Network worden gepubliceerd, zijn uitsluitend bedoeld voor leer- en onderzoeksdoeleinden; De bovenstaande inhoud mag niet worden gebruikt voor commerciële of illegale doeleinden, anders dragen gebruikers alle gevolgen. De informatie op deze site komt van het internet, en auteursrechtconflicten hebben niets met deze site te maken. Je moet bovenstaande inhoud volledig van je computer verwijderen binnen 24 uur na het downloaden. Als je het programma leuk vindt, steun dan de echte software, koop registratie en krijg betere echte diensten. Als er sprake is van een inbreuk, neem dan contact met ons op via e-mail.

Mail To:help@itsvse.com