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 that is 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 Klasse C von Klasse B abgeleitet wird, und Klasse B von Klasse A abgeleitet wird, erbt Klasse C die in Klasse B und A deklarierten Member.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.

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 kann so den Code der Basisklasse wiederverwenden, ohne diesen erneut implementieren zu müssen.The derived class can thereby reuse the code in the base class without having to re-implement it. Sie können der abgeleiteten Klasse mehr Member hinzufügen.In the derived class, you can add more members. Auf diese Art erweitert die abgeleitete Klasse die Funktionalität der Basisklasse.In this manner, 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 beinhalten einen Konstruktor, weil Konstruktoren nicht vererbt werden.These include a constructor, because constructors are not 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.

KlassenvererbungClass Inheritance
KlassenvererbungClass inheritance

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.

// 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;
    }


    protected int GetNextID()
    {
        // currentID is a static field. It is incremented each time a new
        // instance of WorkItem is created.
        return ++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()
    {
        return String.Format("{0} - {1}", 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;
    }
}

class Program
{
    static void Main()
    {
        // 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());

        // Keep the console open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/* 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 virtuell deklariert, kann eine abgeleitete Klasse die Methode mit ihrer eigenen Implementierung außer Kraft setzen.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 abstrakt deklariert, muss diese Methode in jeder nicht abstrakten Klasse außer Kraft gesetzt 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 Schlüsselwort new vermeiden möchten.You can declare a class as abstract if you want to prevent direct instantiation by using the new keyword. Wenn Sie dies machen, kann die Klasse nur verwendet werden, wenn eine neue Klasse von ihr abgeleitet wird.If you do this, the 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 does not 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 are not abstract themselves must provide the implementation for any abstract methods from an abstract base class. Weitere Informationen zu abstrakten Klassen 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, der einer abstrakten Basisklasse leicht ähnelt, die nur aus zwei abstrakten Membern besteht.An interface is a reference type that is somewhat similar to an abstract base class that consists of only abstract members. Wenn eine Klasse eine Schnittstelle implementiert, muss sie eine Implementierung für alle Member der Schnittstelle bereitstellen.When a class implements an interface, it must provide an implementation for all the members of the interface. Ein 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 do not necessarily have an "is a" relationship. Die System.IEquatable<T>-Schnittstelle kann z.B. von jeder beliebigen Klasse oder Struktur implementiert werden, die es Clientcode ermöglichen muss, ermitteln zu können, ob zwei Objekte des Typs äquivalent sind (allerdings definiert der Typ Äquivalenz).For example, the System.IEquatable<T> interface can be implemented by any class or struct that has to enable client code to determine whether two objects of the type are equivalent (however the type defines equivalence). Animal impliziert nicht dieselbe Art einer „ist ein“-Beziehung, wie sie zwischen einer Basis- und einer abgeleiteten Klasse besteht (z.B. ist ein IEquatable<T> ein Mammal).IEquatable<T> does not 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.

Weitere Ableitung verhindernPreventing 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 versiegelt 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 zu abstrakten Klassen finden Sie unter Abstrakte und versiegelte Klassen und Klassenmember.For more information, see Abstract and Sealed Classes and Class Members.

Das Verbergen von Membern der Basisklasse in einer abgeleiteten KlasseDerived 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 nicht dazu vorgesehen ist, den Basismember außer Kraft zu setzen.The new modifier can be used to explicitly indicate that the member is not intended to be an override of the base member. Das Verwenden von new ist nicht erforderlich, aber es wird eine Compilerwarnung generiert, wenn new nicht verwendet wird.The use of new is not required, but a compiler warning will be generated if new is not 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

C#-ProgrammierhandbuchC# Programming Guide
Klassen und StrukturenClasses and Structs
classclass
structstruct