Anmerkung
Der Zugriff auf diese Seite erfordert eine Genehmigung. Du kannst versuchen, dich anzumelden oder die Verzeichnisse zu wechseln.
Der Zugriff auf diese Seite erfordert eine Genehmigung. Du kannst versuchen , die Verzeichnisse zu wechseln.
Der abstract Modifizierer gibt an, dass das Ziel über eine fehlende oder unvollständige Implementierung verfügt. Verwenden Sie den abstrakten Modifizierer mit Klassen, Methoden, Eigenschaften, Indexern und Ereignissen. Verwenden Sie den abstract-Modifizierer in einer Klassendeklaration, um anzugeben, dass die Klasse nur die Basisklasse für andere Klassen sein und nicht selbst instanziiert werden soll. Nicht abstrakte Klassen, die von der abstrakten Klasse abgeleitet werden, müssen Elemente implementieren, die als abstrakt gekennzeichnet sind.
Die C#-Sprachreferenz dokumentiert die zuletzt veröffentlichte Version der C#-Sprache. Außerdem enthält sie eine erste Dokumentation zu Funktionen in der öffentlichen Vorschau für die kommende Sprachversion.
In der Dokumentation werden alle Features identifiziert, die in den letzten drei Versionen der Sprache oder in der aktuellen öffentlichen Vorschau eingeführt wurden.
Tipp
Informationen dazu, wann ein Feature erstmals in C# eingeführt wurde, finden Sie im Artikel zum Versionsverlauf der C#-Sprache.
Abstrakte Klassen können sowohl abstrakte Member enthalten (die keine Implementierung aufweisen und in abgeleiteten Klassen überschrieben werden müssen) als auch vollständig implementierte Member (z. B. reguläre Methoden, Eigenschaften und Konstruktoren). Mit diesem Feature können abstrakte Klassen allgemeine Funktionen bereitstellen und gleichzeitig abgeleitete Klassen zum Implementieren bestimmter abstrakter Member erforderlich sein.
Hinweis
Schnittstellenmmber sind abstract standardmäßig.
Abstrakte Klasse mit gemischten Elementen
Im folgenden Beispiel wird eine abstrakte Klasse veranschaulicht, die sowohl implementierte Methoden als auch abstrakte Member enthält:
namespace LanguageKeywords;
public abstract class Vehicle
{
protected string _brand;
// Constructor - implemented method in abstract class
public Vehicle(string brand) => _brand = brand;
// Implemented method - provides functionality that all vehicles share
public string GetInfo() => $"This is a {_brand} vehicle.";
// Another implemented method
public virtual void StartEngine() => Console.WriteLine($"{_brand} engine is starting...");
// Abstract method - must be implemented by derived classes
public abstract void Move();
// Abstract property - must be implemented by derived classes
public abstract int MaxSpeed { get; }
}
public class Car : Vehicle
{
public Car(string brand) : base(brand) { }
// Implementation of abstract method
public override void Move() => Console.WriteLine($"{_brand} car is driving on the road.");
// Implementation of abstract property
public override int MaxSpeed => 200;
}
public class Boat : Vehicle
{
public Boat(string brand) : base(brand) { }
// Implementation of abstract method
public override void Move() => Console.WriteLine($"{_brand} boat is sailing on the water.");
// Implementation of abstract property
public override int MaxSpeed => 50;
}
public class AbstractExample
{
public static void Examples()
{
// Cannot instantiate abstract class: Vehicle v = new Vehicle("Generic"); // Error!
Car car = new Car("Toyota");
Boat boat = new Boat("Yamaha");
// Using implemented methods from abstract class
Console.WriteLine(car.GetInfo());
car.StartEngine();
// Using abstract methods implemented in derived class
car.Move();
Console.WriteLine($"Max speed: {car.MaxSpeed} km/h");
Console.WriteLine();
Console.WriteLine(boat.GetInfo());
boat.StartEngine();
boat.Move();
Console.WriteLine($"Max speed: {boat.MaxSpeed} km/h");
}
}
class Program
{
static void Main()
{
AbstractExample.Examples();
}
}
/* Output:
This is a Toyota vehicle.
Toyota engine is starting...
Toyota car is driving on the road.
Max speed: 200 km/h
This is a Yamaha vehicle.
Yamaha engine is starting...
Yamaha boat is sailing on the water.
Max speed: 50 km/h
*/
In diesem Beispiel stellt die Vehicle abstrakte Klasse Folgendes bereit:
-
Implementierte Member:
GetInfo()Methode,StartEngine()Methode und Konstruktor – diese Member bieten allgemeine Funktionen für alle Fahrzeuge. -
Abstrakte Elemente:
Move()Methode undMaxSpeedEigenschaft - diese Member müssen von jedem bestimmten Fahrzeugtyp implementiert werden.
Mit diesem Design kann die abstrakte Klasse gemeinsam genutzte Funktionen bereitstellen und gleichzeitig sicherstellen, dass abgeleitete Klassen fahrzeugspezifisches Verhalten implementieren.
Von einer abstrakten Klasse abgeleitete konkrete Klasse
In diesem Beispiel muss die Klasse Square eine Implementierung von GetArea bereitstellen, da sie von Shape abgeleitet ist:
abstract class Shape
{
public abstract int GetArea();
}
class Square : Shape
{
private int _side;
public Square(int n) => _side = n;
// GetArea method is required to avoid a compile-time error.
public override int GetArea() => _side * _side;
static void Main()
{
var sq = new Square(12);
Console.WriteLine($"Area of the square = {sq.GetArea()}");
}
}
// Output: Area of the square = 144
Abstrakte Klassen weisen die folgenden Funktionen auf:
- Sie können keine Instanz einer abstrakten Klasse erstellen.
- Eine abstrakte Klasse kann abstrakte Methoden und Accessoren enthalten.
- Eine abstrakte Klasse kann auch implementierte Methoden, Eigenschaften, Felder und andere Member enthalten, die Funktionen für abgeleitete Klassen bereitstellen.
- Sie können den
sealedModifizierer nicht für eine abstrakte Klasse verwenden, da die beiden Modifizierer eine entgegengesetzte Bedeutung haben. Dersealed-Modifizierer verhindert das Vererben einer Klasse, und derabstract-Modifizierer erfordert das Vererben einer Klasse. - Eine nicht abstrakte Klasse, die von einer abstrakten Klasse abgeleitet wurde, muss Implementierungen aller geerbten abstrakten Methoden und Accessoren enthalten.
Verwenden Sie den abstract Modifizierer in einer Methode oder Eigenschaftsdeklaration, um anzugeben, dass die Methode oder Eigenschaft keine Implementierung enthält.
Abstrakte Methoden weisen die folgenden Funktionen auf:
Eine abstrakte Methode ist implizit eine virtuelle Methode.
Abstrakte Methodendeklarationen sind nur in abstrakten Klassen zulässig.
Da eine abstrakte Methodendeklaration keine tatsächliche Implementierung bereitstellt, gibt es keinen Methodentext. Die Methodendeklaration endet einfach mit einem Semikolon. Beispiel:
public abstract void MyMethod();Die Implementierung wird durch eine Methode
overridebereitgestellt, die ein Mitglied einer nicht abstrakten Klasse ist.Es ist ein Fehler, die
staticvirtualModifizierer in einer abstrakten Methodendeklaration in einemclassTyp zu verwenden. Sie können Schnittstellen deklarieren undstatic virtualMethoden verwendenstatic abstract.Abstrakte Eigenschaften verhalten sich wie abstrakte Methoden – sie unterscheiden sich lediglich in der Deklarations- und Aufrufsyntax.
Es ist ein Fehler, den
abstractModifizierer für eine statische Eigenschaft in einemclassTyp zu verwenden. Sie können schnittstellendeklarationen oderstatic virtualEigenschaften deklarierenstatic abstract.Eine abstrakte geerbte Eigenschaft kann in einer abgeleiteten Klasse überschrieben werden, indem eine Eigenschaftsdeklaration eingeschlossen wird, die den
overrideModifizierer verwendet.
Weitere Informationen zu abstrakten Klassen finden Sie unter Abstrakte und versiegelte Klassen und Klassenmember.
Eine abstrakte Klasse muss eine Implementierung für alle Schnittstellenmember bereitstellen. Eine abstrakte Klasse, die eine Schnittstelle implementiert, ordnet die Schnittstellenmethoden möglicherweise abstrakten Methoden zu. Beispiel:
interface I
{
void M();
}
abstract class C : I
{
public abstract void M();
}
Im folgenden Beispiel wird die Klasse DerivedClass von einer abstrakten Klasse BaseClassabgeleitet. Die abstrakte Klasse enthält eine abstrakte Methode, AbstractMethod, und zwei abstrakte Eigenschaften, X und Y.
// Abstract class
abstract class BaseClass
{
protected int _x = 100;
protected int _y = 150;
// Abstract method
public abstract void AbstractMethod();
// Abstract properties
public abstract int X { get; }
public abstract int Y { get; }
}
class DerivedClass : BaseClass
{
public override void AbstractMethod()
{
_x++;
_y++;
}
public override int X // overriding property
{
get
{
return _x + 10;
}
}
public override int Y // overriding property
{
get
{
return _y + 10;
}
}
static void Main()
{
var o = new DerivedClass();
o.AbstractMethod();
Console.WriteLine($"x = {o.X}, y = {o.Y}");
}
}
// Output: x = 111, y = 161
Wenn Sie beim vorherigen Beispiel versuchen, die abstrakte Klasse mithilfe des folgenden Anweisungsbeispiels zu instanziieren:
BaseClass bc = new BaseClass(); // Error
Sie erhalten eine Fehlermeldung, die besagt, dass der Compiler keine Instanz der abstrakten Klasse "BaseClass" erstellen kann. Dennoch können Sie einen abstrakten Klassenkonstruktor verwenden, wie im folgenden Beispiel gezeigt.
public abstract class Shape
{
public string Color { get; set; }
// Constructor of the abstract class
protected Shape(string color)
{
Color = color;
Console.WriteLine($"Created a shape with color {color}.");
}
// Abstract method that must be implemented by derived classes
public abstract double CalculateArea();
}
public class Square : Shape
{
public double Side { get; set; }
// Constructor of the derived class calling the base class constructor
public Square(string color, double side) : base(color)
{
Side = side;
}
public override double CalculateArea()
{
return Side * Side;
}
}
public class Program
{
public static void Main(string[] args)
{
Square square = new Square("red", 5);
Console.WriteLine($"Area of the square: {square.CalculateArea()}");
}
}
Die Shape Klasse wird deklariert abstract, was bedeutet, dass Sie sie nicht direkt instanziieren können. Stattdessen dient sie als Blaupause für andere Klassen.
- Obwohl Sie keine Objekte einer abstrakten Klasse erstellen können, kann sie dennoch über einen Konstruktor verfügen. Dieser Konstruktor ist in der Regel
protected, was bedeutet, dass nur abgeleitete Klassen darauf zugreifen können. In diesem Fall verwendet derShape-Konstruktor einencolor-Parameter und initialisiert dieColor-Eigenschaft. Außerdem wird eine Meldung auf der Konsole ausgegeben. Derpublic Square(string color, double side) : base(color)-Teil ruft den Konstruktor der Basisklasse (Shape) auf und übergibt das Argumentcoloran ihn. - In der
ShapeKlasse akzeptiert der definierte Konstruktor eine Farbe als Parameterprotected Shape(string color). Dies bedeutet, dass C# keinen standardmäßigen parameterlosen Konstruktor automatisch bereitstellt. Abgeleitete Klassen müssen den: base(color)Ausdruck verwenden, um den Basiskonstruktor aufzurufen. Durch Festlegen des Standardwerts auf Farbeprotected Shape(string color="green")wird der: base(color)Ausdruck in abgeleiteten Klassen weggelassen. Der Konstruktorprotected Shape(string color="green")legt die Farbe auf Grün fest.
C#-Programmiersprachenspezifikation
Weitere Informationen erhalten Sie unter C#-Sprachspezifikation. Die Sprachspezifikation ist die verbindliche Quelle für die Syntax und Verwendung von C#.