Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
V jazyce C# může mít metoda v odvozené třídě stejný název jako metoda v základní třídě. Můžete určit, jak metody spolu interagují, pomocí klíčových slov new a override.
override Modifikátor rozšiřuje metodu základní třídy virtual a new modifikátor skryje přístupnou metodu základní třídy. Rozdíl je znázorněn v příkladech v tomto tématu.
V konzolové aplikaci deklarujte 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");
}
}
Main V metodě deklarujte proměnné bc, dca bcdc.
bcje typuBaseClassa jeho hodnota je typuBaseClass.dcje typuDerivedClassa jeho hodnota je typuDerivedClass.bcdcje typuBaseClassa jeho hodnota je typuDerivedClass. Jedná se o proměnnou, na které je potřeba věnovat pozornost.
Protože bc a bcdc mají typ BaseClass, mají pouze přímý přístup k Method1, ledaže používáte přetypování. Proměnná dc má přístup k oběma Method1 a Method2. Tyto relace se zobrazují 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 metodu do BaseClasssouboru . Podpis této metody odpovídá podpisu Method2 metody v DerivedClass.
public void Method2()
{
Console.WriteLine("Base - Method2");
}
Vzhledem k tomu, že BaseClass nyní má metodu Method2, lze přidat druhý volací příkaz pro proměnné BaseClass, 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();
Nové klíčové slovo
Když sestavíte projekt, uvidíte, že přidání metody Method2 v BaseClass způsobuje upozornění. Upozornění říká, že Method2 metoda v DerivedClass skrytí Method2 metody v BaseClass. Pokud chcete tento výsledek způsobit, doporučujeme použít new klíčové slovo v Method2 definici. Alternativně můžete přejmenovat některou z Method2 metod pro vyřešení upozornění, ale to není vždy praktické.
Před přidáním newspusťte program a zobrazte výstup vytvořený dalšími příkazy volání. Zobrazí se následující výsledky.
// Output:
// Base - Method1
// Base - Method2
// Base - Method1
// Derived - Method2
// Base - Method1
// Base - Method2
Klíčové new slovo zachovává relace, které tento výstup vytvoří, ale potlačí upozornění. Proměnné, které mají typ BaseClass, nadále přistupují ke členům BaseClass, a proměnná, která má typ DerivedClass, nejprve přistupuje k členům DerivedClass a pak zvažuje členy zděděné z BaseClass.
Chcete-li potlačit upozornění, přidejte new modifikátor do definice Method2 in DerivedClass, jak je znázorněno v následujícím kódu. Modifikátor lze přidat před nebo za public.
public new void Method2()
{
Console.WriteLine("Derived - Method2");
}
Spusťte program znovu a ověřte, že se výstup nezměnil. Ověřte také, že se upozornění už nezobrazuje. Pomocí new tvrdíte, že si uvědomujete, že člen, který upravujete, skrývá člena zděděného ze základní třídy. Další informace o skrytí jména prostřednictvím dědičnosti naleznete v novém Modifikátoru.
Klíčová slova virtuální a překračování
Chcete-li toto chování kontrastovat s účinky použití override, přidejte následující metodu do DerivedClass.
override Modifikátor lze přidat před nebo za public.
public override void Method1()
{
Console.WriteLine("Derived - Method1");
}
Přidejte modifikátor virtual do definice Method1 v BaseClass.
virtual Modifikátor lze přidat před nebo za public.
public virtual void Method1()
{
Console.WriteLine("Base - Method1");
}
Spusťte projekt znovu. Všimněte si zejména posledních dvou řádků následujícího výstupu.
// Output:
// Base - Method1
// Base - Method2
// Derived - Method1
// Derived - Method2
// Derived - Method1
// Base - Method2
Použití modifikátoru override umožňuje bcdc přístup k Method1 metodě, která je definována v DerivedClass. Obvykle se jedná o požadované chování v hierarchiích dědičnosti. Chcete, aby objekty, které mají hodnoty vytvořené z odvozené třídy, používaly metody definované v odvozené třídě. Toto chování dosáhnete použitím override k rozšíření metody základní třídy.
Následující kód obsahuje úplný 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");
}
}
}
Přepsání a nové v odvozených třídách
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é z ní ConvertibleCar a Minivan. Základní třída obsahuje metodu DescribeCar . Tato metoda zobrazí základní popis auta a potom zavolá ShowDetails, aby poskytla další informace. Každá ze tří tříd definuje metodu ShowDetails .
new Modifikátor se používá k definování ShowDetails ve ConvertibleCar třídě.
override Modifikátor se používá k definování ShowDetails ve Minivan třídě.
// 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.");
}
}
Testovací příklady, která verze ShowDetails se volá. Následující metoda , TestCars1deklaruje instanci každé třídy a potom volá DescribeCar na 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.
Car car2 = new ConvertibleCar();
car2.DescribeCar();
System.Console.WriteLine("----------");
Minivan car3 = new Minivan();
car3.DescribeCar();
System.Console.WriteLine("----------");
}
TestCars1 vytvoří následující výstup. Všimněte si zejména výsledků car2, které pravděpodobně nejsou to, co jste očekávali. Typ objektu je ConvertibleCar, ale DescribeCar nemá přístup k verzi ShowDetails, která je definována ve třídě ConvertibleCar, protože tato metoda je deklarována s new modifikátorem, nikoli s override modifikátorem. V důsledku toho ConvertibleCar objekt zobrazí stejný popis jako Car objekt. Porovnejte výsledky pro car3, což je Minivan objekt. V tomto případě metoda deklarovaná ShowDetails ve Minivan třídě přepíše ShowDetails metodu deklarovanou ve Car třídě a popis zobrazený popis popisuje 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 vytvoří seznam objektů, které mají typ Car. Hodnoty objektů jsou instanciovány z tříd Car, ConvertibleCar a Minivan.
DescribeCar je aplikována 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 jde o stejný výstup, který je zobrazen pomocí TestCars1. Metoda ShowDetailsConvertibleCar třídy není volána bez ohledu na to, zda typ objektu je ConvertibleCar, jako v TestCars1, nebo Car, jako v TestCars2. Naopak car3 volá metodu ShowDetails třídy Minivan v obou případech, ať už má 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 doplňují příklad. Tyto metody volají ShowDetails přímo, nejprve z objektů deklarovaných jako typ ConvertibleCar a Minivan (TestCars3), pak z objektů deklarovaných jako typ Car (TestCars4). Následující kód definuje tyto dvě 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 vytvoří následující výstup, který odpovídá výsledkům z prvního příkladu 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 úplný projekt 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.");
}
}
}