När ska man använda en abstrakt klass mot gränssnitt i C #

När du utformar applikationer är det viktigt att veta när man ska använda en abstrakt klass och när man ska använda ett gränssnitt. Även om abstrakta klasser och gränssnitt på vissa sätt liknar det, finns det viktiga skillnader som avgör vilket som är det bästa valet för vad du försöker åstadkomma. I det här blogginlägget kommer jag att diskutera dessa skillnader och hur man bestämmer när man ska använda vilken.

Det korta svaret: En abstrakt klass låter dig skapa funktionalitet som underklasser kan implementera eller åsidosätta. Ett gränssnitt låter dig bara definiera funktionalitet, inte implementera den. Och medan en klass endast kan utvidga en abstrakt klass kan den dra nytta av flera gränssnitt. 

C # abstrakt klass förklaras

En abstrakt klass är en speciell typ av klass som inte kan instantieras. En abstrakt klass är utformad för att ärvas av underklasser som antingen implementerar eller åsidosätter dess metoder. Med andra ord är abstrakta klasser antingen delvis implementerade eller inte alls implementerade. Du kan ha funktionalitet i din abstrakta klass - metoderna i en abstrakt klass kan vara både abstrakta och konkreta. En abstrakt klass kan ha konstruktörer - detta är en stor skillnad mellan en abstrakt klass och ett gränssnitt. Du kan dra nytta av abstrakta klasser för att designa komponenter och ange en viss nivå av gemensam funktionalitet som måste implementeras av härledda klasser.

C # gränssnitt förklaras

Ett gränssnitt är i grunden ett kontrakt - det har ingen implementering. Ett gränssnitt kan endast innehålla metoddeklarationer; den kan inte innehålla metoddefinitioner. Du kan inte heller ha någon medlemsinformation i ett gränssnitt. Medan en abstrakt klass kan innehålla metoddefinitioner, fält och konstruktörer, kan ett gränssnitt endast ha deklarationer av händelser, metoder och egenskaper. Metoder som deklareras i ett gränssnitt måste implementeras av de klasser som implementerar gränssnittet. Observera att en klass kan implementera mer än ett gränssnitt men endast utöka en klass. Klassen som implementerar gränssnittet bör implementera alla dess medlemmar. Som en abstrakt klass kan ett gränssnitt inte instantieras.

Ska jag använda en abstrakt klass eller ett gränssnitt?

Abstrakta klasser ger dig flexibiliteten att ha vissa konkreta metoder och några andra metoder som de härledda klasserna bör implementera. Om du använder gränssnitt måste du däremot implementera alla metoder i klassen som utökar gränssnittet. En abstrakt klass är ett bra val om du har planer för framtida expansion - dvs. om en framtida expansion sannolikt är i klasshierarkin. Om du vill ge stöd för framtida expansion när du använder gränssnitt måste du utvidga gränssnittet och skapa ett nytt.

På en annan anteckning är det enkelt att lägga till ett nytt gränssnitt i hierarkin om det behövs. Men om du redan har en abstrakt klass i din hierarki kan du inte lägga till en annan - dvs. du kan bara lägga till en abstrakt klass om ingen finns tillgänglig. Du bör använda ett gränssnitt om du vill ha ett avtal om något beteende eller funktionalitet. Du bör inte använda ett gränssnitt om du behöver skriva samma kod för gränssnittsmetoderna. I det här fallet bör du använda en abstrakt klass, definiera metoden en gång och återanvända den efter behov. Använd gränssnitt för att koppla bort din applikations kod från specifika implementeringar av den, eller för att begränsa åtkomsten till medlemmar av en viss typ.

Som Microsofts dokumentation av gränssnitt säger:

Genom att använda gränssnitt kan du till exempel inkludera beteende från flera källor i en klass. Den förmågan är viktig i C # eftersom språket inte stöder flera arv av klasser. Dessutom måste du använda ett gränssnitt om du vill simulera arv för struct, eftersom de faktiskt inte kan ärva från en annan struktur eller klass.

Implicita och explicita gränssnittsimplementeringar

Gränssnitt kan implementeras implicit eller uttryckligen. Låt mig förklara hur dessa två implementeringar skiljer sig åt. Tänk på ett gränssnitt som heter IBusinessLogic.

offentligt gränssnitt IBusinessLogic

{

   ogiltigt Initiera ();

}

Följande klass med namnet BusinessLogicimplementerar IBusinessLogicgränssnittet.

offentlig klass BusinessLogic: IBusinessLogic

{

   offentligt ogiltigt Initiera ()

   {

       // Någon kod

   }

}

Du kan skapa en instans av BusinessLogicklassen uttryckligen och sedan ringa Initialize()metoden enligt nedan.

 IBusinessLogic businessLogic = ny BusinessLogic ();

businessLogic.Initialize ();

Följande kodavsnitt illustrerar hur du kan implementera IBusinessLogicgränssnittet implicit.

offentlig klass BusinessLogic: IBusinessLogic

{

   ogiltig IBusinessLogic.Initialize ()

   {

   }

}

Du kan nu åberopa Initialize()metoden på samma sätt med en hänvisning till IBusinessLogicgränssnittet. Skillnaden i de två tillvägagångssätten är att när du implementerar gränssnittet uttryckligen i din klass, är du tvungen att åberopa en metod för ditt gränssnitt med endast en referens till gränssnittet. Följande kodavsnitt fungerar därför inte, dvs. kompilerar inte.

 BusinessLogic businessLogic = ny BusinessLogic ();

businessLogic.Initialize ();

Hur man gör mer i C #:

  • När ska man använda en abstrakt klass mot gränssnitt i C #
  • Hur man arbetar med AutoMapper i C #
  • Hur man använder lambdauttryck i C #
  • Hur man arbetar med Action, Func och Predicate-delegater i C #
  • Hur man arbetar med delegater i C #
  • Hur man implementerar en enkel logger i C #
  • Hur man arbetar med attribut i C #
  • Hur man arbetar med log4net i C #
  • Hur man implementerar förvarets designmönster i C #
  • Hur man arbetar med reflektion i C #
  • Hur man arbetar med filsystemwatcher i C #
  • Hur man utför lat initialisering i C #
  • Hur man arbetar med MSMQ i C #
  • Hur man arbetar med förlängningsmetoder i C #
  • Hur vi lambdauttryck i C #
  • När ska du använda det flyktiga nyckelordet i C #
  • Så här använder du nyckelordet i C #
  • Hur man implementerar polymorfism i C #
  • Hur man bygger din egen uppgiftsschemaläggare i C #
  • Hur man arbetar med RabbitMQ i C #
  • Hur man arbetar med en tuple i C #
  • Utforska virtuella och abstrakta metoder i C #