Wann müssen die Schlüsselwörter "override" und "new" verwendet werden? (C#-Programmierhandbuch)Knowing When to Use Override and New Keywords (C# Programming Guide)

In C# kann eine Methode in einer abgeleiteten Klasse den gleichen Namen wie eine Methode in einer Basisklasse haben.In C#, a method in a derived class can have the same name as a method in the base class. Sie können mit den Schlüsselwörtern new und override festlegen, wie die Methoden interagieren.You can specify how the methods interact by using the new and override keywords. Der override-Modifizierer erweitert die Methode der Basisklasse, und der new-Modifizierer verbirgt sie.The override modifier extends the base class method, and the new modifier hides it. Der Unterschied wird in den Beispielen in diesem Thema veranschaulicht.The difference is illustrated in the examples in this topic.

Deklarieren Sie in einer Konsolenanwendung die folgenden beiden Klassen: BaseClass und DerivedClass.In a console application, declare the following two classes, BaseClass and DerivedClass. DerivedClass erbt von BaseClass.DerivedClass inherits from BaseClass.

class BaseClass  
{  
    public void Method1()  
    {  
        Console.WriteLine("Base - Method1");  
    }  
}  

class DerivedClass : BaseClass  
{  
    public void Method2()  
    {  
        Console.WriteLine("Derived - Method2");  
    }  
}  

Deklarieren Sie in der Main-Methode die Variablen bc, dc und bcdc.In the Main method, declare variables bc, dc, and bcdc.

  • bc ist vom Typ BaseClass, und sein Wert ist vom Typ BaseClass.bc is of type BaseClass, and its value is of type BaseClass.

  • dc ist vom Typ DerivedClass, und sein Wert ist vom Typ DerivedClass.dc is of type DerivedClass, and its value is of type DerivedClass.

  • bcdc ist vom Typ BaseClass, und sein Wert ist vom Typ DerivedClass.bcdc is of type BaseClass, and its value is of type DerivedClass. Auf diese Variable müssen Sie achten.This is the variable to pay attention to.

Da bc und bcdc vom Typ BaseClass sind, können sie nur direkt auf Method1 zugreifen, es sei denn, sie verwenden Umwandlungen.Because bc and bcdc have type BaseClass, they can only directly access Method1, unless you use casting. Die Variable dc kann sowohl auf Method1 als auch auf Method2 zugreifen.Variable dc can access both Method1 and Method2. Diese Beziehungen werden im folgenden Code gezeigt.These relationships are shown in the following code.

class Program  
{  
    static void Main(string[] args)  
    {  
        BaseClass bc = new BaseClass();  
        DerivedClass dc = new DerivedClass();  
        BaseClass bcdc = new DerivedClass();  

        bc.Method1();  
        dc.Method1();  
        dc.Method2();  
        bcdc.Method1();  
    }  
    // Output:  
    // Base - Method1  
    // Base - Method1  
    // Derived - Method2  
    // Base - Method1  
}  

Fügen Sie als Nächstes die folgende Method2-Methode in BaseClass hinzu.Next, add the following Method2 method to BaseClass. Die Signatur dieser Methode entspricht der Signatur der Method2-Methode in DerivedClass.The signature of this method matches the signature of the Method2 method in DerivedClass.

public void Method2()  
{  
    Console.WriteLine("Base - Method2");  
}  

Weil BaseClass jetzt über eine Method2-Methode verfügt, kann eine zweite aufrufende Anweisung für die BaseClass-Variablen bc und bcdc hinzugefügt werden, wie in folgendem Code gezeigt.Because BaseClass now has a Method2 method, a second calling statement can be added for BaseClass variables bc and bcdc, as shown in the following code.

bc.Method1();  
bc.Method2();  
dc.Method1();  
dc.Method2();  
bcdc.Method1();  
bcdc.Method2();  

Wenn Sie das Projekt erstellen, stellen sie fest, dass das Hinzufügen der Method2-Methode in BaseClass zu einer Warnmeldung führt.When you build the project, you see that the addition of the Method2 method in BaseClass causes a warning. In der Warnmeldung steht, dass die Method2-Methode in DerivedClass die Method2-Methode in BaseClass verbirgt.The warning says that the Method2 method in DerivedClass hides the Method2 method in BaseClass. Es wird empfohlen, dass Sie das new-Schlüsselwort in der Method2-Definition verwenden, wenn Sie möchten, dass es zu diesem Ergebnis kommt.You are advised to use the new keyword in the Method2 definition if you intend to cause that result. Alternativ können Sie eine der Method2-Methoden umbenennen, um die Warnung aufzulösen. Dies muss jedoch nicht immer praktikabel sein.Alternatively, you could rename one of the Method2 methods to resolve the warning, but that is not always practical.

Führen Sie das Programm aus, bevor Sie new hinzufügen, um die Ausgabe der zusätzlichen aufrufenden Anweisungen zu überprüfen.Before adding new, run the program to see the output produced by the additional calling statements. Die folgenden Ergebnisse werden angezeigt.The following results are displayed.

// Output:  
// Base - Method1  
// Base - Method2  
// Base - Method1  
// Derived - Method2  
// Base - Method1  
// Base - Method2  

Das new-Schlüsselwort erhält die Beziehungen, die diese Ausgabe verursachen, aber es unterdrückt die Warnmeldung.The new keyword preserves the relationships that produce that output, but it suppresses the warning. Die Variablen vom Typ BaseClass greifen weiterhin auf die Member von BaseClass zu, und die Variable des Typs DerivedClass greift weiterhin zuerst auf Member in DerivedClass zu, und kümmert sich dann um von BaseClass geerbte Member.The variables that have type BaseClass continue to access the members of BaseClass, and the variable that has type DerivedClass continues to access members in DerivedClass first, and then to consider members inherited from BaseClass.

Fügen sie den new-Modifizierer in die Definition von Method2 in DerivedClass ein, wie in folgendem Code gezeigt, um die Warnmeldung zu unterdrücken.To suppress the warning, add the new modifier to the definition of Method2 in DerivedClass, as shown in the following code. Der Modifizierer kann vor oder hinter public eingefügt werden.The modifier can be added before or after public.

public new void Method2()  
{  
    Console.WriteLine("Derived - Method2");  
}  

Führen Sie das Programm erneut aus, um sicherzustellen, dass die Ausgabe gleich geblieben ist.Run the program again to verify that the output has not changed. Überprüfen Sie außerdem, ob die Warnung weiterhin angezeigt wird.Also verify that the warning no longer appears. Wenn Sie new verwenden, bestätigen Sie, dass Ihnen bewusst ist, dass der davon modifizierte Member einen Member verbirgt, der von der Basisklasse vererbt wird.By using new, you are asserting that you are aware that the member that it modifies hides a member that is inherited from the base class. Weitere Informationen zum Verbergen von Namen durch die Vererbung finden Sie unter new-Modifizierer.For more information about name hiding through inheritance, see new Modifier.

Fügen Sie die folgende Methode in DerivedClass ein, um dieses Verhalten den Auswirkungen durch das Verwenden von override gegenüberzustellen.To contrast this behavior to the effects of using override, add the following method to DerivedClass. Der override-Modifizierer kann vor oder hinter public eingefügt werden.The override modifier can be added before or after public.

public override void Method1()  
{  
    Console.WriteLine("Derived - Method1");  
}  

Fügen Sie der Definition von Method1 in BaseClass den virtual-Modifizierer hinzu.Add the virtual modifier to the definition of Method1 in BaseClass. Der virtual-Modifizierer kann vor oder hinter public eingefügt werden.The virtual modifier can be added before or after public.

public virtual void Method1()  
{  
    Console.WriteLine("Base - Method1");  
}  

Führen Sie das Projekt erneut aus.Run the project again. Achten Sie besonders auf die letzten beiden Zeilen der folgenden Ausgabe.Notice especially the last two lines of the following output.

// Output:  
// Base - Method1  
// Base - Method2  
// Derived - Method1  
// Derived - Method2  
// Derived - Method1  
// Base - Method2  

Durch den override-Modifizierer kann bcdc auf die in DerivedClass definierte Method1-Methode zugreifen.The use of the override modifier enables bcdc to access the Method1 method that is defined in DerivedClass. Normalerweise ist dies das gewünschte Verhalten in Vererbungshierarchien.Typically, that is the desired behavior in inheritance hierarchies. Objekte sollten Werte aufweisen, die aus der abgeleiteten Klasse erzeugt werden, um die Methoden, die in der abgeleiteten Klasse definiert sind, verwenden zu können.You want objects that have values that are created from the derived class to use the methods that are defined in the derived class. Dieses Verhalten erzielen Sie, indem Sie override verwenden, um die Methode der Basisklasse zu erweitern.You achieve that behavior by using override to extend the base class method.

Der folgende Code umfasst das vollständige Beispiel.The following code contains the full example.

using System;  
using System.Text;  

namespace OverrideAndNew  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            BaseClass bc = new BaseClass();  
            DerivedClass dc = new DerivedClass();  
            BaseClass bcdc = new DerivedClass();  

            // The following two calls do what you would expect. They call  
            // the methods that are defined in BaseClass.  
            bc.Method1();  
            bc.Method2();  
            // Output:  
            // Base - Method1  
            // Base - Method2  

            // The following two calls do what you would expect. They call  
            // the methods that are defined in DerivedClass.  
            dc.Method1();  
            dc.Method2();  
            // Output:  
            // Derived - Method1  
            // Derived - Method2  

            // The following two calls produce different results, depending   
            // on whether override (Method1) or new (Method2) is used.  
            bcdc.Method1();  
            bcdc.Method2();  
            // Output:  
            // Derived - Method1  
            // Base - Method2  
        }  
    }  

    class BaseClass  
    {  
        public virtual void Method1()  
        {  
            Console.WriteLine("Base - Method1");  
        }  

        public virtual void Method2()  
        {  
            Console.WriteLine("Base - Method2");  
        }  
    }  

    class DerivedClass : BaseClass  
    {  
        public override void Method1()  
        {  
            Console.WriteLine("Derived - Method1");  
        }  

        public new void Method2()  
        {  
            Console.WriteLine("Derived - Method2");  
        }  
    }  
}  

Das folgende Beispiel veranschaulicht ähnliches Verhalten in unterschiedlichen Kontexten.The following example illustrates similar behavior in a different context. Im Beispiel werden drei Klassen definiert: eine Basisklasse mit dem Namen Car und zwei Klassen, die von dieser Basisklasse abgeleitet werden, ConvertibleCar und Minivan.The example defines three classes: a base class named Car and two classes that are derived from it, ConvertibleCar and Minivan. Die Basisklasse enthält eine DescribeCar-Methode.The base class contains a DescribeCar method. Die Methode zeigt eine grundlegende Beschreibung eines Autos und ruft dann ShowDetails auf, um zusätzliche Informationen bereitzustellen.The method displays a basic description of a car, and then calls ShowDetails to provide additional information. Jede der drei Klassen definiert eine ShowDetails-Methode.Each of the three classes defines a ShowDetails method. Der new-Modifizierer wird für die Definition von ShowDetails in der ConvertibleCar-Klasse verwendet.The new modifier is used to define ShowDetails in the ConvertibleCar class. Der override-Modifizierer wird für die Definition von ShowDetails in der Minivan-Klasse verwendet.The override modifier is used to define ShowDetails in the Minivan class.

// Define the base class, Car. The class defines two methods,  
// DescribeCar and ShowDetails. DescribeCar calls ShowDetails, and each derived  
// class also defines a ShowDetails method. The example tests which version of  
// ShowDetails is selected, the base class method or the derived class method.  
class Car  
{  
    public void DescribeCar()  
    {  
        System.Console.WriteLine("Four wheels and an engine.");  
        ShowDetails();  
    }  

    public virtual void ShowDetails()  
    {  
        System.Console.WriteLine("Standard transportation.");  
    }  
}  

// Define the derived classes.  

// Class ConvertibleCar uses the new modifier to acknowledge that ShowDetails  
// hides the base class method.  
class ConvertibleCar : Car  
{  
    public new void ShowDetails()  
    {  
        System.Console.WriteLine("A roof that opens up.");  
    }  
}  

// Class Minivan uses the override modifier to specify that ShowDetails  
// extends the base class method.  
class Minivan : Car  
{  
    public override void ShowDetails()  
    {  
        System.Console.WriteLine("Carries seven people.");  
    }  
}  

In dem Beispiel wird geprüft, welche Version von ShowDetails aufgerufen wird.The example tests which version of ShowDetails is called. Die folgende Methode, TestCars1, deklariert eine Instanz jeder Klasse und ruft dann DescribeCar auf jeder Instanz auf.The following method, TestCars1, declares an instance of each class, and then calls DescribeCar on each instance.

public static void TestCars1()  
{  
    System.Console.WriteLine("\nTestCars1");  
    System.Console.WriteLine("----------");  

    Car car1 = new Car();  
    car1.DescribeCar();  
    System.Console.WriteLine("----------");  

    // Notice the output from this test case. The new modifier is  
    // used in the definition of ShowDetails in the ConvertibleCar  
    // class.    

    ConvertibleCar car2 = new ConvertibleCar();  
    car2.DescribeCar();  
    System.Console.WriteLine("----------");  

    Minivan car3 = new Minivan();  
    car3.DescribeCar();  
    System.Console.WriteLine("----------");  
}  

TestCars1 erzeugt die folgende Ausgabe.TestCars1 produces the following output. Achten Sie besonders auf die Ergebnis für car2, die wahrscheinlich nicht dem entsprechen, was Sie erwartet haben.Notice especially the results for car2, which probably are not what you expected. Der Typ des Objekts ist ConvertibleCar. Allerdings greift DescribeCar nicht auf die Version von ShowDetails zu, die in der ConvertibleCar-Klasse definiert wurde, da diese Methode mit dem new-Modifizierer und nicht dem override-Modifizierer deklariert wird.The type of the object is ConvertibleCar, but DescribeCar does not access the version of ShowDetails that is defined in the ConvertibleCar class because that method is declared with the new modifier, not the override modifier. Deshalb zeigt ein ConvertibleCar-Objekt die gleiche Beschreibung wie ein Car-Objekt an.As a result, a ConvertibleCar object displays the same description as a Car object. Stellen Sie die Ergebnis von car3 gegenüber, das ein Minivan-Objekt ist.Contrast the results for car3, which is a Minivan object. In diesem Fall setzt die ShowDetails-Methode, die in der Minivan-Klasse deklariert wurde, die ShowDetails-Methode, die in der Car-Klasse deklariert wurde, außer Kraft, und es wird eine Beschreibung eines Minivans angezeigt.In this case, the ShowDetails method that is declared in the Minivan class overrides the ShowDetails method that is declared in the Car class, and the description that is displayed describes a minivan.

// TestCars1  
// ----------  
// Four wheels and an engine.  
// Standard transportation.  
// ----------  
// Four wheels and an engine.  
// Standard transportation.  
// ----------  
// Four wheels and an engine.  
// Carries seven people.  
// ----------  

TestCars2 erstellt eine Liste von Objekten des Typs Car.TestCars2 creates a list of objects that have type Car. Die Werte der Objekte werden von den Klassen Car, ConvertibleCar und Minivan instanziiert.The values of the objects are instantiated from the Car, ConvertibleCar, and Minivan classes. DescribeCar wird auf jedem Element in der Liste aufgerufen.DescribeCar is called on each element of the list. Der folgende Code veranschaulicht die Definition von TestCars2.The following code shows the definition of TestCars2.

public static void TestCars2()  
{  
    System.Console.WriteLine("\nTestCars2");  
    System.Console.WriteLine("----------");  

    var cars = new List<Car> { new Car(), new ConvertibleCar(),   
        new Minivan() };  

    foreach (var car in cars)  
    {  
        car.DescribeCar();  
        System.Console.WriteLine("----------");  
    }  
}  

Die folgende Ausgabe wird angezeigt.The following output is displayed. Beachten Sie, dass sie der Ausgabe, die von TestCars1 angezeigt wird, entspricht.Notice that it is the same as the output that is displayed by TestCars1. Die ShowDetails-Methode der ConvertibleCar-Klasse wird nicht aufgerufen, unabhängig davon, ob der Typ des Objekts ConvertibleCar, wie in TestCars1, oder Car, wie in TestCars2, ist.The ShowDetails method of the ConvertibleCar class is not called, regardless of whether the type of the object is ConvertibleCar, as in TestCars1, or Car, as in TestCars2. Umgekehrt ruft car3 in beiden Fällen die ShowDetails-Methode der Minivan-Klasse auf, egal, ob es vom Typ Minivan oder Car ist.Conversely, car3 calls the ShowDetails method from the Minivan class in both cases, whether it has type Minivan or type Car.

// TestCars2  
// ----------  
// Four wheels and an engine.  
// Standard transportation.  
// ----------  
// Four wheels and an engine.  
// Standard transportation.  
// ----------  
// Four wheels and an engine.  
// Carries seven people.  
// ----------  

Die Methoden TestCars3 und TestCars4 schließen das Beispiel ab.Methods TestCars3 and TestCars4 complete the example. Diese Methoden rufen ShowDetails direkt auf. Zuerst von Objekte, die mit den Typen ConvertibleCar und Minivan (TestCars3) deklariert wurden, und anschließend von Objekten, die mit dem Typ Car (TestCars4) deklariert wurden.These methods call ShowDetails directly, first from objects declared to have type ConvertibleCar and Minivan (TestCars3), then from objects declared to have type Car (TestCars4). Der folgende Code definiert diese beiden Methoden.The following code defines these two methods.

public static void TestCars3()  
{  
    System.Console.WriteLine("\nTestCars3");  
    System.Console.WriteLine("----------");  
    ConvertibleCar car2 = new ConvertibleCar();  
    Minivan car3 = new Minivan();  
    car2.ShowDetails();  
    car3.ShowDetails();  
}  

public static void TestCars4()  
{  
    System.Console.WriteLine("\nTestCars4");  
    System.Console.WriteLine("----------");  
    Car car2 = new ConvertibleCar();  
    Car car3 = new Minivan();  
    car2.ShowDetails();  
    car3.ShowDetails();  
}  

Die Methoden erzeugen folgende Ausgabe, die den Ergebnissen des ersten Beispiels in diesem Thema entspricht.The methods produce the following output, which corresponds to the results from the first example in this topic.

// TestCars3  
// ----------  
// A roof that opens up.  
// Carries seven people.  

// TestCars4  
// ----------  
// Standard transportation.  
// Carries seven people.  

Der folgende Code veranschaulicht das vollständige Projekt und dessen Ausgabe.The following code shows the complete project and its output.

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  

namespace OverrideAndNew2  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            // Declare objects of the derived classes and test which version  
            // of ShowDetails is run, base or derived.  
            TestCars1();  

            // Declare objects of the base class, instantiated with the  
            // derived classes, and repeat the tests.  
            TestCars2();  

            // Declare objects of the derived classes and call ShowDetails  
            // directly.  
            TestCars3();  

            // Declare objects of the base class, instantiated with the  
            // derived classes, and repeat the tests.  
            TestCars4();  
        }  

        public static void TestCars1()  
        {  
            System.Console.WriteLine("\nTestCars1");  
            System.Console.WriteLine("----------");  

            Car car1 = new Car();  
            car1.DescribeCar();  
            System.Console.WriteLine("----------");  

            // Notice the output from this test case. The new modifier is  
            // used in the definition of ShowDetails in the ConvertibleCar  
            // class.    
            ConvertibleCar car2 = new ConvertibleCar();  
            car2.DescribeCar();  
            System.Console.WriteLine("----------");  

            Minivan car3 = new Minivan();  
            car3.DescribeCar();  
            System.Console.WriteLine("----------");  
        }  
        // Output:  
        // TestCars1  
        // ----------  
        // Four wheels and an engine.  
        // Standard transportation.  
        // ----------  
        // Four wheels and an engine.  
        // Standard transportation.  
        // ----------  
        // Four wheels and an engine.  
        // Carries seven people.  
        // ----------  

        public static void TestCars2()  
        {  
            System.Console.WriteLine("\nTestCars2");  
            System.Console.WriteLine("----------");  

            var cars = new List<Car> { new Car(), new ConvertibleCar(),   
                new Minivan() };  

            foreach (var car in cars)  
            {  
                car.DescribeCar();  
                System.Console.WriteLine("----------");  
            }  
        }  
        // Output:  
        // TestCars2  
        // ----------  
        // Four wheels and an engine.  
        // Standard transportation.  
        // ----------  
        // Four wheels and an engine.  
        // Standard transportation.  
        // ----------  
        // Four wheels and an engine.  
        // Carries seven people.  
        // ----------  

        public static void TestCars3()  
        {  
            System.Console.WriteLine("\nTestCars3");  
            System.Console.WriteLine("----------");  
            ConvertibleCar car2 = new ConvertibleCar();  
            Minivan car3 = new Minivan();  
            car2.ShowDetails();  
            car3.ShowDetails();  
        }  
        // Output:  
        // TestCars3  
        // ----------  
        // A roof that opens up.  
        // Carries seven people.  

        public static void TestCars4()  
        {  
            System.Console.WriteLine("\nTestCars4");  
            System.Console.WriteLine("----------");  
            Car car2 = new ConvertibleCar();  
            Car car3 = new Minivan();  
            car2.ShowDetails();  
            car3.ShowDetails();  
        }  
        // Output:  
        // TestCars4  
        // ----------  
        // Standard transportation.  
        // Carries seven people.  
    }  

    // Define the base class, Car. The class defines two virtual methods,  
    // DescribeCar and ShowDetails. DescribeCar calls ShowDetails, and each derived  
    // class also defines a ShowDetails method. The example tests which version of  
    // ShowDetails is used, the base class method or the derived class method.  
    class Car  
    {  
        public virtual void DescribeCar()  
        {  
            System.Console.WriteLine("Four wheels and an engine.");  
            ShowDetails();  
        }  

        public virtual void ShowDetails()  
        {  
            System.Console.WriteLine("Standard transportation.");  
        }  
    }  

    // Define the derived classes.  

    // Class ConvertibleCar uses the new modifier to acknowledge that ShowDetails  
    // hides the base class method.  
    class ConvertibleCar : Car  
    {  
        public new void ShowDetails()  
        {  
            System.Console.WriteLine("A roof that opens up.");  
        }  
    }  

    // Class Minivan uses the override modifier to specify that ShowDetails  
    // extends the base class method.  
    class Minivan : Car  
    {  
        public override void ShowDetails()  
        {  
            System.Console.WriteLine("Carries seven people.");  
        }  
    }  

}  

Siehe auchSee Also

C#-ProgrammierhandbuchC# Programming Guide
Klassen und StrukturenClasses and Structs
Versionsverwaltung mit den Schlüsselwörtern "override" und "new"Versioning with the Override and New Keywords
basebase
abstractabstract