Programmering

Når skal jeg bruke en abstrakt klasse vs. grensesnitt i C #

Når du designer applikasjoner, er det viktig å vite når du skal bruke en abstrakt klasse og når du skal bruke et grensesnitt. Selv om abstrakte klasser og grensesnitt på noen måter virker like, er det viktige forskjeller som vil avgjøre hvilket som er det beste valget for det du prøver å oppnå. I dette blogginnlegget vil jeg diskutere disse forskjellene og hvordan du skal bestemme når du skal bruke hvilke.

Det korte svaret: En abstrakt klasse lar deg lage funksjonalitet som underklasser kan implementere eller overstyre. Et grensesnitt lar deg bare definere funksjonalitet, ikke implementere den. Og mens en klasse bare kan utvide en abstrakt klasse, kan den dra nytte av flere grensesnitt.

C # abstrakt klasse forklart

En abstrakt klasse er en spesiell type klasse som ikke kan instantiseres. En abstrakt klasse er designet for å bli arvet av underklasser som enten implementerer eller overstyrer metodene. Med andre ord er abstrakte klasser enten delvis implementert eller ikke implementert i det hele tatt. Du kan ha funksjonalitet i din abstrakte klasse - metodene i en abstrakt klasse kan være både abstrakte og konkrete. En abstrakt klasse kan ha konstruktører - dette er en stor forskjell mellom en abstrakt klasse og et grensesnitt. Du kan dra nytte av abstrakte klasser for å designe komponenter og spesifisere noe nivå av vanlig funksjonalitet som må implementeres av avledede klasser.

C # grensesnitt forklart

Et grensesnitt er i utgangspunktet en kontrakt - det har ingen implementering. Et grensesnitt kan bare inneholde metodedeklarasjoner; den kan ikke inneholde metodedefinisjoner. Du kan heller ikke ha medlemsdata i et grensesnitt. Mens en abstrakt klasse kan inneholde metodedefinisjoner, felt og konstruktører, kan et grensesnitt bare ha erklæringer om hendelser, metoder og egenskaper. Metoder deklarert i et grensesnitt må implementeres av klassene som implementerer grensesnittet. Merk at en klasse kan implementere mer enn ett grensesnitt, men bare utvide en klasse. Klassen som implementerer grensesnittet, skal implementere alle medlemmene. Som en abstrakt klasse kan ikke et grensesnitt instantieres.

Bør jeg bruke en abstrakt klasse eller et grensesnitt?

Abstrakte klasser gir deg fleksibilitet til å ha visse konkrete metoder og noen andre metoder som de avledede klassene skal implementere. Hvis du derimot bruker grensesnitt, må du implementere alle metodene i klassen som utvider grensesnittet. En abstrakt klasse er et godt valg hvis du har planer om fremtidig utvidelse - dvs. hvis en fremtidig utvidelse sannsynligvis er i klassehierarkiet. Hvis du vil gi støtte for fremtidig utvidelse når du bruker grensesnitt, må du utvide grensesnittet og opprette et nytt.

På en annen tone er det enkelt å legge til et nytt grensesnitt til hierarkiet hvis det er nødvendig. Men hvis du allerede har en abstrakt klasse i hierarkiet, kan du ikke legge til en annen, dvs. du kan bare legge til en abstrakt klasse hvis ingen er tilgjengelige. Du bør bruke et grensesnitt hvis du vil ha en kontrakt om noe oppførsel eller funksjonalitet. Du bør ikke bruke et grensesnitt hvis du trenger å skrive den samme koden for grensesnittmetodene. I dette tilfellet bør du bruke en abstrakt klasse, definere metoden en gang, og bruke den etter behov. Bruk grensesnitt for å koble applikasjonens kode fra spesifikke implementeringer av den, eller for å begrense tilgangen til medlemmer av en bestemt type.

Som Microsofts dokumentasjon av grensesnitt sier:

Ved å bruke grensesnitt kan du for eksempel inkludere atferd fra flere kilder i en klasse. Denne muligheten er viktig i C # fordi språket ikke støtter flere arv av klasser. I tillegg må du bruke et grensesnitt hvis du vil simulere arv for strukturer, fordi de faktisk ikke kan arve fra en annen struktur eller klasse.

Implisitte og eksplisitte grensesnittimplementeringer

Grensesnitt kan implementeres implisitt eller eksplisitt. La meg forklare hvordan disse to implementeringene er forskjellige. Vurder et grensesnitt som heter IBusinessLogic.

offentlig grensesnitt IBusinessLogic

{

ugyldig Initialiser ();

}

Følgende klasse heter BusinessLogic implementerer IBusinessLogic grensesnitt.

offentlig klasse BusinessLogic: IBusinessLogic

{

offentlig ugyldig Initialiser ()

   {

// Noe kode

   }

}

Du kan opprette en forekomst av BusinessLogic klasse eksplisitt og ring deretter Initialiser () metoden som vist nedenfor.

 IBusinessLogic businessLogic = ny BusinessLogic ();

businessLogic.Initialize ();

Følgende kodebit illustrerer hvordan du kan implementere IBusinessLogic grensesnitt implisitt.

offentlig klasse BusinessLogic: IBusinessLogic

{

ugyldig IBusinessLogic.Initialize ()

   {

   }

}

Du kan nå påberope deg Initialiser () metode på samme måte ved hjelp av en referanse til IBusinessLogic grensesnitt. Forskjellen i de to tilnærmingene er at når du implementerer grensesnittet eksplisitt i klassen din, er du tvunget til å påkalle en metode for grensesnittet ditt ved kun å bruke en referanse til grensesnittet. Derfor fungerer ikke følgende kodebit, dvs. vil ikke kompilere.

 BusinessLogic businessLogic = ny BusinessLogic ();

businessLogic.Initialize ();

Hvordan gjøre mer i C #:

  • Når skal jeg bruke en abstrakt klasse vs. grensesnitt i C #
  • Hvordan jobbe med AutoMapper i C #
  • Hvordan bruke lambdauttrykk i C #
  • Hvordan jobbe med Action-, Func- og Predicate-delegater i C #
  • Hvordan jobbe med delegater i C #
  • Slik implementerer du en enkel logger i C #
  • Hvordan jobbe med attributter i C #
  • Hvordan jobbe med log4net i C #
  • Slik implementerer du mønsteret for depotdesign i C #
  • Hvordan jobbe med refleksjon i C #
  • Hvordan jobbe med filsystemwatcher i C #
  • Hvordan utføre lat initialisering i C #
  • Hvordan jobbe med MSMQ i C #
  • Hvordan jobbe med utvidelsesmetoder i C #
  • Hvordan vi lambdauttrykk i C #
  • Når skal du bruke det flyktige nøkkelordet i C #
  • Slik bruker du avkastningsnøkkelordet i C #
  • Hvordan implementere polymorfisme i C #
  • Hvordan lage din egen oppgaveplanlegger i C #
  • Hvordan jobbe med RabbitMQ i C #
  • Hvordan jobbe med en tuple i C #
  • Utforske virtuelle og abstrakte metoder i C #