Ich habe eine Art von R & amp; D gemacht und bin verwirrt mit dem Konzept einer abstrakten Klasse.
Was ich an einer abstrakten Klasse weiß, ist, dass sie konkrete Methoden enthalten kann und virtuelle Methoden enthalten kann. Es kann eine abstrakte Methode enthalten oder auch nicht, und es kann Felder enthalten und die direkte Erstellung von Instanzen einschränken.
Aber wir können all dies in einer einfachen Basisklasse erreichen (eine Hinzufügung von virtuellen Methoden wird viel bewirken, weil eine Basisklasse mit virtuellen Methoden dort keine Implementierung enthält und die Überschreibung dieselbe ist wie eine abstrakte Methode). Warum brauchen wir dann eine abstrakte Klasse, obwohl die Schnittstelle mehrere Vererbungen und Ereignisse unterstützt?
Aber wir können all dies in einer einfachen Basisklasse erreichen
Nein, das kannst du nicht. Sie können keine nicht abstrakte Klasse mit abstrakten Methoden haben (Methoden, bei denen die Signatur definiert ist, aber keine Implementierung angegeben ist, also erzwungene abgeleitete Klassen zur Bereitstellung einer Implementierung).
Abstrakte Klassen existieren , damit sie eine Kombination aus implementierten Methoden und abstrakten Methoden bereitstellen können.
Sie können versuchen, abstract
classes zu vermeiden, indem Sie konkrete Implementierungen verwenden, die nichts tun, aber sie haben eine Reihe von Nachteilen:
Betrachte auch nicht-void Methoden in einer Welt ohne Abstrakt. Sie müssten werfen (d. H.% Co_de%) oder einen ungültigen Wert zurückgeben (d. H.% Co_de%). Das könnte viel schlimmer sein als eine Methode, die einfach nichts tut.
Der Hauptunterschied besteht darin, dass Sie mit dem Compiler keine abstrakte Klasse instanziieren können, während Sie eine Basisklasse instanziieren könnten (was möglicherweise keinen Sinn ergibt).
%Vor% Beachten Sie, dass die abstrakten Methoden mit der Variablen d
überschrieben wurden (sonst hätte die DerivedType
-Klasse einen Compilerfehler).
Da Sie eine Menge Verwirrung noch kommentieren, gebe ich Ihnen das Beispiel, das ich wirklich hatte, das dieses Konzept für mich klickte. Stellen Sie sich vor, Sie machen ein Tower Defense Spiel. Du hast eine Turmklasse und jeder Turm hat die Fähigkeit zu attackieren, also machst du eine abstrakte Turmklasse wie diese:
%Vor%Jetzt kann ich mehrere Turmklassen machen:
%Vor%Wenn Sie nun eine Liste von Türmen deklarieren wollen, können Sie schreiben:
%Vor%dann iteriere durch sie und mache sie alle anzugreifen:
%Vor%Und jede Klasse hat garantiert einen Angriff implementiert, weil sie als abstrakt gekennzeichnet wurde und wenn nicht, wäre das ein Kompilierungsfehler. Nun könnte das alles mit einer Basisklasse gemacht werden, außer eine Basisklasse würde dies erlauben:
%Vor% Wenn es jetzt versucht, den Angriff auf new Tower()
aufzurufen, wird es eine leere abstrakte Methode treffen, was wir nicht wollen. Um also zu verbieten, etwas als generischen Turm zu deklarieren, machen wir die Klasse abstrakt, dann wissen wir, dass alles seine eigene Definition von Attack
hat und etwas tun wird.
Es gibt einige Klassen, die in der realen Welt einfach nicht existieren und sollten daher konzeptionell als abstract
markiert werden. Betrachten Sie beispielsweise abstract class Animal
. Es gibt kein "Tier" in der realen Welt. Stattdessen gibt es konkrete Tierarten wie Dog
, Cat
, etc.
Eine einfache Antwort könnte sein: -
Basisklassen haben eigene Implementierungen für Methoden, und diese Implementierungen können in einer geerbten Klasse verwendet / hinzugefügt werden. Sie können eine Basisklasse instanziieren
Abstrakte Klassen enthalten Deklarationen für Klassenmethoden. Jede Klasse, die die abstrakte Klasse erbt, muss ihre abstrakten Methoden implementieren oder sich selbst abstrahieren. Sie können eine abstrakte Klasse nicht instanziieren
Beispiel: -
%Vor%Klasse B kann Method1 weiterhin aus Klasse A verwenden, da es geerbt ist. Und wenn Klasse A abstrakt sein soll, dann würden alle Methoden wie Methode 2 deklariert und müssten in Klasse B implementiert werden, damit sie verwendet werden kann.
Tags und Links .net c# abstract-class base-class