Sdílet prostřednictvím


Víte, kdy použít přepsat a nová klíčová slova (C# Příručka programování)

V jazyce C# může metoda odvozené třídy mít stejný název jako metoda v základní třídě.Můžete určit, jak interagovat pomocí metody nové a potlačit klíčová slova.override Modifikátor rozšiřuje metoda základní třídy a new modifikátor skryje ji.Rozdíl je znázorněna v příkladech v tomto tématu.

Aplikace konzoly deklarovat následující dvě třídy BaseClass a DerivedClass.DerivedClass dědí 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 je BaseClass, a jeho hodnota je typu BaseClass.

  • dctyp je DerivedClass, a jeho hodnota je typu DerivedClass.

  • bcdctyp je BaseClass, a jeho hodnota je typu DerivedClass.Toto je proměnná věnovat pozornost.

Protože bc a bcdc typu BaseClass, můžete přímo přistupovat Method1, pokud použijete obsazení.Proměnná dc přístup i k Method1 a Method2.Tyto vztahy jsou uvedeny v následujícím kódu.

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
}

Dále přidejte následující Method2 metody BaseClass.Podpis odpovídá podpisu této metody Method2 metoda v DerivedClass.

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

Protože BaseClass má nyní Method2 metodou, druhé volání příkazu lze přidat pro BaseClass proměnné bc a bcdc, jak je znázorněno v následujícím kódu.

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

Při vytváření projektu, viz přídavek Method2 metoda v BaseClass způsobuje upozornění.Upozornění uvádí, že Method2 metoda v DerivedClass skryje Method2 metoda v BaseClass.Doporučuje se použít new klíčové slovo v Method2 definice, pokud máte v úmyslu způsobit výsledku.Také jeden z nelze přejmenovat Method2 metody řešení upozornění, ale není vždy praktické.

Před přidáním new, spusťte program a zobrazí výstup vyrábí další příkazy pro volání.Zobrazí se následující výsledky.

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

new Klíčové slovo zachová vztahy, které produkci takového výstupu, ale potlačí upozornění.Proměnné, které mají typ BaseClass i nadále přístup členové BaseClassa proměnnou typu DerivedClass i nadále přístup členů v DerivedClass první a potom zvažte členy zděděné z BaseClass.

Chcete-li potlačit varování, přidejte new modifikátor definici Method2 v DerivedClass, jak je znázorněno v následujícím kódu.Na modifikátor lze přidat před nebo po public.

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

Spusťte program znovu ověřit výstup nezměnil.Ověřte také, že již se zobrazí upozornění.Pomocí new, potvrzující, že jste si vědomi, že člen, který upraví skryje člen, který je zděděna ze základní třídy.Další informace o skrytí názvu prostřednictvím dědičnosti naleznete v Modifikátor nové (C#-Reference).

Pro kontrast pomocí účinky tohoto chování override, přidat metodu DerivedClass.override Modifikátor lze přidat před nebo po public.

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

Přidat virtual modifikátor definici Method1 v BaseClass.virtual Modifikátor lze přidat před nebo po public.

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

Projekt znovu spuste.Všimněte si zejména poslední dva řádky následující výstup.

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

Použití override umožňuje modifikátor bcdc přístup Method1 metoda, která je definována v DerivedClass.Obvykle se jedná o požadované chování v hierarchiích dědičnosti.Chcete objekty, které mají hodnoty, které jsou vytvořeny z odvozené třídy metody, které jsou definovány v odvozené třídě.Toto chování můžete dosáhnout pomocí override k rozšíření metody základní třídy.

Následující kód obsahuje celý příklad.

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

Následující příklad ukazuje podobné chování v jiném kontextu.Příklad definuje tři třídy: základní třídu pojmenovanou Car a dvě třídy odvozené od, ConvertibleCar a Minivan.Obsahuje základní třídy DescribeCar metoda.Metoda zobrazí základní popis auta a pak zavolá ShowDetails poskytnout další informace.Každý tři třídy definuje ShowDetails metoda.new Modifikátor slouží k definování ShowDetails v ConvertibleCar třídy.override Modifikátor slouží k definování ShowDetails v Minivan třídy.

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

Příklad testuje verzi ShowDetails se nazývá.Následující metoda TestCars1, deklaruje instanci třídy a pak zavolá DescribeCar pro každou instanci.

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 následující výstup.Všimněte si zejména výsledky pro car2, které jsou pravděpodobně není očekávaného.Typ objektu je ConvertibleCar, ale DescribeCar nemá přístup na verzi ShowDetails definovanou v ConvertibleCar třídy, protože tato metoda je deklarována s new , modifikátor, není override modifikátor.Výsledkem ConvertibleCar objektu zobrazí stejný popis jako Car objektu.Výsledky pro kontrast car3, která je Minivan objektu.V tomto případě ShowDetails metoda, která je deklarována v Minivan třída přepíše ShowDetails metoda, která je deklarována v Car třídy a popis, který je zobrazen minivan popisuje.

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

TestCars2Vytvoří seznam objektů, které mají typ Car.Hodnoty objektů instancemi Car, ConvertibleCar, a Minivan tříd.DescribeCarnazývá se na každý prvek seznamu.Následující kód ukazuje definici 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("----------");
    }
}

Zobrazí se následující výstup.Všimněte si, že je stejný jako výstup, který je zobrazen TestCars1.ShowDetails Metodu ConvertibleCar není názvem třídy, bez ohledu na to, zda je typ objektu ConvertibleCar, jako v TestCars1, nebo Car, jako v TestCars2.Naopak car3 volání ShowDetails metoda z Minivan třídy v obou případech, zda typ Minivan nebo 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 a TestCars4 příklad dokončit.Tyto metody volat ShowDetails přímo, nejdříve objekty deklarované mít typ ConvertibleCar a Minivan (TestCars3), pak z objektů, které mají typ deklarován Car (TestCars4).Následující kód definuje těchto dvou metod.

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 vytvoří následující výstup, který odpovídá výsledky z první příklad v tomto tématu.

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

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

Následující kód ukazuje dokončení projektu a jeho výstup.

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

}

Viz také

Referenční dokumentace

Třídy a struktur (Příručka programování C#)

Správa verzí s přepsat a nová klíčová slova (Příručka programování C#)

Base (C#-Reference)

abstraktní (C#-Reference)

Koncepty

Příručka programování C#