Udostępnij za pośrednictwem


Wiedząc, kiedy należy używać Override i nowe słowa kluczowe (C# Programming Guide)

W języku C# metoda w klasie pochodnej może mieć taką samą nazwę jak metoda w klasie podstawowej.Można określić interakcji przy użyciu metody Nowy i zastąpić słowa kluczowe.override Modyfikator rozszerza metoda klasy bazowej i new modyfikator ukrywa go.Ilustruje różnicę w przykładach w tym temacie.

W aplikacji konsoli, należy zadeklarować następujące dwie klasy BaseClass i DerivedClass.DerivedClassdziedziczy z BaseClass.

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

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

In the Main method, declare variables bc, dc, and bcdc.

  • bcTyp jest BaseClass, a jego wartość jest typu BaseClass.

  • dcTyp jest DerivedClass, a jego wartość jest typu DerivedClass.

  • bcdcTyp jest BaseClass, a jego wartość jest typu DerivedClass.Jest to zmienna do zwrócenia uwagi.

Ponieważ bc i bcdc typ BaseClass, mają dostęp tylko bezpośrednio Method1, chyba że Użyj rzutowania.Zmienna dc można uzyskać dostęp zarówno Method1 i Method2.Relacje te przedstawiono w poniższym kodzie.

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
}

Następnie należy dodać następujący Method2 metoda BaseClass.Podpis pasuje do podpisania niniejszej metody Method2 metodę w DerivedClass.

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

Ponieważ BaseClass ma teraz Method2 metodę, druga instrukcja wywołującego można dodawać do BaseClass zmiennych bc i bcdc, jak pokazano w poniższym kodzie.

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

Podczas tworzenia projektu zobaczysz, że dodanie Method2 metodę w BaseClass powoduje, że ostrzeżenie.Ostrzeżenie mówi, że Method2 metodę w DerivedClass ukrywa Method2 metodę w BaseClass.Zalecane jest użycie new słowa kluczowego w Method2 definicji, jeśli zamierzasz powodować tego wyniku.Alternatywnie, można zmienić jeden z Method2 metody rozwiązywania ostrzeżenie, ale nie zawsze jest praktyczne.

Przed dodaniem new, uruchom program, aby zobaczyć wytworzonych przez dodatkowe instrukcje wywołującego.Następujące wyniki są wyświetlane.

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

new Słowa kluczowego zachowuje relacje, które produkują tej produkcji, ale go znosi ostrzeżenie.Zmienne, które mają typ BaseClass nadal korzystać członkowie BaseClassi zmiennej, która ma typ DerivedClass nadal dostęp członków w DerivedClass pierwszy, a następnie rozważyć członków dziedziczonych od BaseClass.

Pomija ostrzeżenia, należy dodać new modyfikator definicji Method2 w DerivedClass, jak pokazano w poniższym kodzie.Modyfikator mogą zostać dodane przed lub po public.

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

Uruchom program ponownie, aby sprawdzić, czy nie zmieniono dane wyjściowe.Sprawdź także, ostrzeżenie nie będzie już wyświetlany.Za pomocą new, są potwierdzające, że są świadomi, że element członkowski, który modyfikuje ukrywa element członkowski, który jest dziedziczona z klasy bazowej.Aby uzyskać więcej informacji na temat nazwy ukrywanie poprzez dziedziczenie zobacz nowe modyfikator (C# odniesienia).

Aby kontrast to zachowanie skutki za pomocą override, dodaj następującą metodę do DerivedClass.override Modyfikator mogą zostać dodane przed lub po public.

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

Dodaj virtual modyfikator definicji Method1 w BaseClass.virtual Modyfikator mogą zostać dodane przed lub po public.

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

Ponownie uruchom projekt.Należy zauważyć, szczególnie ostatnie dwa wiersze następujące dane wyjściowe.

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

Użycie override modyfikatora umożliwia bcdc dostępu Method1 metodę, która jest zdefiniowana w DerivedClass.Zazwyczaj jest to pożądane zachowanie w hierarchii dziedziczenia.Ma obiektów, które mają wartości, które są tworzone na podstawie klasy dziedziczącej metody które są zdefiniowane w klasie pochodnej.To zachowanie można osiągnąć za pomocą override rozszerzyć metoda klasy bazowej.

Poniższy kod zawiera pełny przykład.

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");
        }
    }
}

Poniższy przykład ilustruje podobne zachowanie w innym kontekście.Przykład definiuje trzy klasy: klasa podstawowa o nazwie Car i dwie klasy pochodne, ConvertibleCar i Minivan.Klasa podstawowa zawiera DescribeCar metody.Metoda Wyświetla opis podstawowych samochodu, a następnie wywołuje ShowDetails dodatkowych informacji.Każda z trzech klas definiuje ShowDetails metody.new Modyfikator służy do definiowania ShowDetails w ConvertibleCar klasy.override Modyfikator służy do definiowania ShowDetails w Minivan klasy.

// 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.");
    }
}

Przykład testów wersji ShowDetails jest wywoływana.Następujące metody, TestCars1, deklaruje instancję każdej klasy, a następnie wywołuje DescribeCar w każdym wystąpieniu.

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("----------");
}

TestCars1generuje następujące dane wyjściowe.Należy zauważyć, zwłaszcza wyniki dla car2, które prawdopodobnie są niż oczekiwano.Typ obiektu jest ConvertibleCar, ale DescribeCar nie ma dostępu do wersji ShowDetails zdefiniowanego w ConvertibleCar klasy, ponieważ metoda ta jest zadeklarowana z new , modyfikator nie override modyfikator.W wyniku ConvertibleCar obiekt wyświetlany ten sam opis co Car obiektu.Kontrast wyniki dla car3, który jest Minivan obiektu.W przypadku ShowDetails metodę, która jest zadeklarowana w Minivan klasy przesłonięcia ShowDetails metodę, która jest zadeklarowana w Car klasy i opis, który jest wyświetlany opisuje Mały furgon.

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

TestCars2Tworzy listę obiektów, które mają typ Car.Wartości obiekty są tworzone z Car, ConvertibleCar, i Minivan klasy.DescribeCarnazywa się dla każdego elementu listy.Poniższy kod przedstawia definicję 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("----------");
    }
}

Następujące dane wyjściowe są wyświetlane.Należy zauważyć, że jest taka sama jak produkcja, która jest wyświetlana przez TestCars1.ShowDetails Metoda ConvertibleCar klasy nie jest wywoływana, niezależnie od tego, czy typ obiektu jest ConvertibleCar, jak w TestCars1, lub Car, jak w TestCars2.Odwrotnie car3 wywołania ShowDetails metodę z Minivan klasy w obu przypadkach, czy ma typ Minivan lub Car.

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

Metody TestCars3 i TestCars4 wykonania przykładu.Wywołania tych metod ShowDetails bezpośrednio, najpierw z obiektów zadeklarowane mieć typ ConvertibleCar i Minivan (TestCars3), następnie od obiektów, uznanych za mające typ Car (TestCars4).Poniższy kod definiuje te dwie metody.

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();
}

Metody generują następujące wyniki, która odpowiada wyniki z pierwszego przykładu, w tym temacie.

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

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

Poniższy kod przedstawia dane wyjściowe i zakończenie projektu.

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.");
        }
    }

}

Zobacz też

Informacje

Klasy i strukturach (Podręcznik programowania C#)

Przechowywanie wersji z Override i nowe słowa kluczowe (Podręcznik programowania C#)

podstawy (C# odniesienia)

streszczenie (C# odniesienia)

Koncepcje

Podręcznik programowania C#