Vererbung (C#-Programmierhandbuch)Inheritance (C# Programming Guide)

Die Vererbung ist, zusammen mit der Kapselung und der Polymorphie, eines der drei primären Charakteristika des objektorientierten Programmierens.Inheritance, together with encapsulation and polymorphism, is one of the three primary characteristics of object-oriented programming. Die Vererbung ermöglicht die Erstellung neuer Klassen, die in anderen Klassen definiertes Verhalten wieder verwenden, erweitern und ändern.Inheritance enables you to create new classes that reuse, extend, and modify the behavior defined in other classes. Die Klasse, deren Member vererbt werden, wird Basisklasse genannt, und die Klasse, die diese Member erbt, wird abgeleitete Klasse genannt.The class whose members are inherited is called the base class, and the class that inherits those members is called the derived class. Eine abgeleitete Klasse kann nur eine direkte Basisklasse haben.A derived class can have only one direct base class. Doch die Vererbung ist transitiv.However, inheritance is transitive. Wenn ClassC von ClassB und ClassB von ClassA abgeleitet wird, erbt ClassC die Member, die in ClassB und ClassA deklariert wurden.If ClassC is derived from ClassB, and ClassB is derived from ClassA, ClassC inherits the members declared in ClassB and ClassA.

Hinweis

Strukturen unterstützen die Vererbung nicht, aber sie können Schnittstellen implementieren.Structs do not support inheritance, but they can implement interfaces. Weitere Informationen finden Sie unter Schnittstellen.For more information, see Interfaces.

Konzeptuell gesehen ist die abgeleitete Klasse eine Spezialisierung der Basisklasse.Conceptually, a derived class is a specialization of the base class. Wenn Sie beispielsweise eine Basisklasse Animal haben, haben Sie möglicherweise eine abgeleitete Klasse mit dem Namen Mammal und eine andere abgeleitete Klasse mit dem Namen Reptile.For example, if you have a base class Animal, you might have one derived class that is named Mammal and another derived class that is named Reptile. Ein Mammal ist ein Animal, und ein Reptile ist ein Animal, aber jede abgeleitete Klasse repräsentiert unterschiedliche Spezialisierungen der Basisklasse.A Mammal is an Animal, and a Reptile is an Animal, but each derived class represents different specializations of the base class.

Schnittstellendeklarationen können eine Standardimplementierung ihrer Member definieren.Interface declarations may define a default implementation for its members. Diese Implementierungen werden von abgeleiteten Schnittstellen und von Klassen geerbt, die diese Schnittstellen implementieren.These implementations are inherited by derived interfaces, and by classes that implement those interfaces. Weitere Informationen über Standardschnittstellenmethoden finden Sie im Artikel zu Schnittstellen in der Sprachreferenz.For more information on default interface methods, see the article on interfaces in the language reference section.

Wenn Sie eine Klasse definieren, die von einer anderen Klasse abgeleitet werden soll, erhält die abgeleitete Klasse implizit alle Member der Basisklasse – ausgenommen davon sind deren Konstruktoren und Finalizern.When you define a class to derive from another class, the derived class implicitly gains all the members of the base class, except for its constructors and finalizers. Die abgeleitete Klasse verwendet den Code in der Basisklasse wieder, ohne ihn nochmal implementieren zu müssen.The derived class reuses the code in the base class without having to reimplement it. Sie können weitere Member in der abgeleiteten Klasse hinzufügen.You can add more members in the derived class. Die abgeleitete Klasse erweitert die Funktionalität der Basisklasse.The derived class extends the functionality of the base class.

Die folgende Abbildung zeigt eine Klasse WorkItem, die ein Arbeitselement in einem Geschäftsprozess repräsentiert.The following illustration shows a class WorkItem that represents an item of work in some business process. Wie alle Klassen leitet es sich von System.Object ab und erbt dessen Methoden.Like all classes, it derives from System.Object and inherits all its methods. WorkItem fügt von allein fünf Member hinzu.WorkItem adds five members of its own. Diese Member beinhalten einen Konstruktor, weil Konstruktoren nicht vererbt werden.These members include a constructor, because constructors aren't inherited. Die Klasse ChangeRequest erbt von WorkItem und repräsentiert eine bestimmt Art von Arbeitselementen.Class ChangeRequest inherits from WorkItem and represents a particular kind of work item. ChangeRequest fügt den von WorkItem und Object geerbten Membern zwei weitere Member hinzu.ChangeRequest adds two more members to the members that it inherits from WorkItem and from Object. Es muss seinen eigenen Konstruktor hinzufügen, und es fügt auch originalItemID hinzu.It must add its own constructor, and it also adds originalItemID. Die Eigenschaft originalItemID ermöglicht es der ChangeRequest-Instanz, mit dem ursprünglichen WorkItem verknüpft zu werden, für das die Änderungsanforderung gilt.Property originalItemID enables the ChangeRequest instance to be associated with the original WorkItem to which the change request applies.

Diagramm, das die Klassenvererbung zeigt

Das folgende Beispiel zeigt, wie die in der oben stehenden Abbildung veranschaulichten Klassenbeziehungen in C# ausgedrückt werden.The following example shows how the class relationships demonstrated in the previous illustration are expressed in C#. Das Beispiel zeigt auch, wie WorkItem die virtuelle Methode Object.ToString außer Kraft setzt, und wie die ChangeRequest-Klasse die WorkItem-Implementierung der Methode erbt.The example also shows how WorkItem overrides the virtual method Object.ToString, and how the ChangeRequest class inherits the WorkItem implementation of the method. Im ersten Codeblock werden die Klassen definiert:The first block defines the classes:

// WorkItem implicitly inherits from the Object class.
public class WorkItem
{
    // Static field currentID stores the job ID of the last WorkItem that
    // has been created.
    private static int currentID;

    //Properties.
    protected int ID { get; set; }
    protected string Title { get; set; }
    protected string Description { get; set; }
    protected TimeSpan jobLength { get; set; }

    // Default constructor. If a derived class does not invoke a base-
    // class constructor explicitly, the default constructor is called
    // implicitly.
    public WorkItem()
    {
        ID = 0;
        Title = "Default title";
        Description = "Default description.";
        jobLength = new TimeSpan();
    }

    // Instance constructor that has three parameters.
    public WorkItem(string title, string desc, TimeSpan joblen)
    {
        this.ID = GetNextID();
        this.Title = title;
        this.Description = desc;
        this.jobLength = joblen;
    }

    // Static constructor to initialize the static member, currentID. This
    // constructor is called one time, automatically, before any instance
    // of WorkItem or ChangeRequest is created, or currentID is referenced.
    static WorkItem() => currentID = 0;

    // currentID is a static field. It is incremented each time a new
    // instance of WorkItem is created.
    protected int GetNextID() => ++currentID;

    // Method Update enables you to update the title and job length of an
    // existing WorkItem object.
    public void Update(string title, TimeSpan joblen)
    {
        this.Title = title;
        this.jobLength = joblen;
    }

    // Virtual method override of the ToString method that is inherited
    // from System.Object.
    public override string ToString() =>
        $"{this.ID} - {this.Title}";
}

// ChangeRequest derives from WorkItem and adds a property (originalItemID)
// and two constructors.
public class ChangeRequest : WorkItem
{
    protected int originalItemID { get; set; }

    // Constructors. Because neither constructor calls a base-class
    // constructor explicitly, the default constructor in the base class
    // is called implicitly. The base class must contain a default
    // constructor.

    // Default constructor for the derived class.
    public ChangeRequest() { }

    // Instance constructor that has four parameters.
    public ChangeRequest(string title, string desc, TimeSpan jobLen,
                         int originalID)
    {
        // The following properties and the GetNexID method are inherited
        // from WorkItem.
        this.ID = GetNextID();
        this.Title = title;
        this.Description = desc;
        this.jobLength = jobLen;

        // Property originalItemId is a member of ChangeRequest, but not
        // of WorkItem.
        this.originalItemID = originalID;
    }
}

Im nächsten Codeblock wird die Verwendung der Basis- und abgeleiteten Klassen veranschaulicht:This next block shows how to use the base and derived classes:

// Create an instance of WorkItem by using the constructor in the
// base class that takes three arguments.
WorkItem item = new WorkItem("Fix Bugs",
                            "Fix all bugs in my code branch",
                            new TimeSpan(3, 4, 0, 0));

// Create an instance of ChangeRequest by using the constructor in
// the derived class that takes four arguments.
ChangeRequest change = new ChangeRequest("Change Base Class Design",
                                        "Add members to the class",
                                        new TimeSpan(4, 0, 0),
                                        1);

// Use the ToString method defined in WorkItem.
Console.WriteLine(item.ToString());

// Use the inherited Update method to change the title of the
// ChangeRequest object.
change.Update("Change the Design of the Base Class",
    new TimeSpan(4, 0, 0));

// ChangeRequest inherits WorkItem's override of ToString.
Console.WriteLine(change.ToString());
/* Output:
    1 - Fix Bugs
    2 - Change the Design of the Base Class
*/

Abstrakte und virtuelle MethodenAbstract and virtual methods

Wenn eine Basisklasse eine Methode als virtual deklariert, kann eine abgeleitete Klasse die Methode mithilfe des override-Modifizierers mit ihrer eigenen Implementierung überschreiben.When a base class declares a method as virtual, a derived class can override the method with its own implementation. Wenn eine Basisklasse eine Methode als abstract deklariert, muss diese Methode in jeder nicht abstrakten Klasse überschrieben werden, die direkt von dieser Klasse erbt.If a base class declares a member as abstract, that method must be overridden in any non-abstract class that directly inherits from that class. Wenn eine abgeleitete Klasse selbst abstrakt ist, erbt sie abstrakte Member, ohne diese zu implementieren.If a derived class is itself abstract, it inherits abstract members without implementing them. Abstrakte und virtuelle Member sind die Basis für Polymorphie, die das zweite charakteristische Merkmal des objektorientierten Programmierens ist.Abstract and virtual members are the basis for polymorphism, which is the second primary characteristic of object-oriented programming. Weitere Informationen finden Sie unter Polymorphie.For more information, see Polymorphism.

Abstrakte BasisklassenAbstract base classes

Sie können eine Klasse als abstrakt deklarieren, wenn Sie die direkte Instanziierung mit dem new-Operator vermeiden möchten.You can declare a class as abstract if you want to prevent direct instantiation by using the new operator. Eine abstrakte Klasse kann nur verwendet werden, wenn eine neue Klasse von ihr abgeleitet wird.An abstract class can be used only if a new class is derived from it. Eine abstrakte Klasse kann mindestens eine Methodensignatur enthalten, die selbst auch als abstrakt deklariert wurden.An abstract class can contain one or more method signatures that themselves are declared as abstract. Diese Signaturen geben die Parameter und Rückgabewerte an, verfügen aber über keine Implementierung (Methodenkörper).These signatures specify the parameters and return value but have no implementation (method body). Eine abstrakte Klasse muss nicht zwangsläufig abstrakte Member enthalten. Wenn eine Klasse allerdings einen abstrakten Member enthält, muss die Klasse an sich auch als abstrakt deklariert werden.An abstract class doesn't have to contain abstract members; however, if a class does contain an abstract member, the class itself must be declared as abstract. Abgeleitete Klassen, die nicht selbst abstrakt sind, müssen eine Implementierung für jede beliebige abstrakte Methode aus einer abstrakten Basisklasse bereitstellen.Derived classes that aren't abstract themselves must provide the implementation for any abstract methods from an abstract base class. Weitere Informationen finden Sie unter Abstrakte und versiegelte Klassen und Klassenmember.For more information, see Abstract and Sealed Classes and Class Members.

SchnittstellenInterfaces

Eine Schnittstelle ist ein Verweistyp, mit dem eine Gruppe von Membern definiert wird.An interface is a reference type that defines a set of members. Alle Klassen und Strukturen, die diese Schnittstelle implementieren, müssen diese Gruppe von Membern implementieren.All classes and structs that implement that interface must implement that set of members. Eine Schnittstelle kann eine Standardimplementierung für beliebige oder alle dieser Member definieren.An interface may define a default implementation for any or all of these members. Eine Klasse kann mehrere Schnittstellen implementieren, auch wenn sie nur von einer einzelnen direkten Basisklasse ableiten kann.A class can implement multiple interfaces even though it can derive from only a single direct base class.

Schnittstellen werden verwendet, um bestimmte Funktionen zu definieren, die nicht unbedingt in einer „ist ein“-Beziehung zueinander stehen.Interfaces are used to define specific capabilities for classes that don't necessarily have an "is a" relationship. Beispielsweise kann die Schnittstelle System.IEquatable<T> von einer beliebigen Klasse oder Struktur implementiert werden, um zu bestimmen, ob zwei Objekte des Typs äquivalent sind (die Äquivalenz wird jedoch vom Typ definiert).For example, the System.IEquatable<T> interface can be implemented by any class or struct to determine whether two objects of the type are equivalent (however the type defines equivalence). IEquatable<T> impliziert nicht dieselbe Art einer „ist ein“-Beziehung, wie sie zwischen einer Basis- und einer abgeleiteten Klasse besteht (z. B. ist ein Mammal ein Animal).IEquatable<T> doesn't imply the same kind of "is a" relationship that exists between a base class and a derived class (for example, a Mammal is an Animal). Weitere Informationen finden Sie unter Schnittstellen.For more information, see Interfaces.

Verhindern weiterer AbleitungPreventing further derivation

Eine Klasse kann andere Klassen daran hindern, von ihr oder einem ihrer Member zu erben, indem sie sich selbst oder den Member als sealed deklariert.A class can prevent other classes from inheriting from it, or from any of its members, by declaring itself or the member as sealed. Weitere Informationen finden Sie unter Abstrakte und versiegelte Klassen und Klassenmember.For more information, see Abstract and Sealed Classes and Class Members.

Verbergen von Basisklassenmembern durch abgeleitete KlassenDerived class hiding of base class members

Eine abgeleitete Klasse kann Basisklassenmember verbergen, indem sie Member mit demselben Namen und derselben Signatur deklariert.A derived class can hide base class members by declaring members with the same name and signature. Der Modifizierer new kann verwendet werden, um explizit anzugeben, dass der Member den Basismember nicht überschreiben soll.The new modifier can be used to explicitly indicate that the member isn't intended to be an override of the base member. Das Verwenden von new ist nicht erforderlich, aber einer Compilerwarnung wird generiert, wenn new nicht verwendet wird.The use of new isn't required, but a compiler warning will be generated if new isn't used. Weitere Informationen finden Sie unter Versionsverwaltung mit den Schlüsselwörtern „override“ und „new“ und Wann müssen die Schlüsselwörter „override“ und „new“ verwendet werden?.For more information, see Versioning with the Override and New Keywords and Knowing When to Use Override and New Keywords.

Siehe auchSee also