Megosztás a következőn keresztül:


Verziószámozás felülbírálással és új kulcsszavakkal (C# programozási útmutató)

A C#-nyelv úgy lett kialakítva, hogy a különböző kódtárak alap - és származtatott osztályai közötti verziószámozás fejlődjön, és fenntarthassa a visszamenőleges kompatibilitást. Ez például azt jelenti, hogy a C# teljes mértékben támogatja egy új tag bevezetését egy alaposztályban , amelynek neve megegyezik egy származtatott osztály tagjával, és nem vezet váratlan viselkedéshez. Azt is jelenti, hogy az osztálynak explicit módon meg kell állapítania, hogy egy metódus egy örökölt metódus felülbírálására szolgál-e, vagy egy metódus egy új metódus, amely elrejt egy hasonlóan elnevezett öröklött metódust.

A C#-ban a származtatott osztályok olyan metódusokat tartalmazhatnak, amelyek neve megegyezik az alaposztály-metódusokkal.

  • Ha a származtatott osztály metódusát nem előzi meg új vagy felülbíráló kulcsszavak, a fordító figyelmeztetést ad ki, és a metódus úgy fog viselkedni, mintha a new kulcsszó jelen lett volna.

  • Ha a származtatott osztály metódusát megelőzi a new kulcsszó, a metódus az alaposztály metódusától függetlenként van definiálva.

  • Ha a származtatott osztály metódusát megelőzi a override kulcsszó, a származtatott osztály objektumai az alaposztály metódusa helyett ezt a metódust hívják meg.

  • Ahhoz, hogy a kulcsszót override a származtatott osztály metódusára alkalmazza, az alaposztály metódusát virtuálisan kell definiálni.

  • Az alaposztály metódusa meghívható a származtatott osztályból a base kulcsszó használatával.

  • A override, virtualés a kulcsszavak tulajdonságokra, indexelőkre és new eseményekre is alkalmazhatók.

Alapértelmezés szerint a C# metódusok nem virtuálisak. Ha egy metódus virtuálisként van deklarálva, a metódust öröklő bármely osztály implementálhatja a saját verzióját. A metódus virtuálissá tételéhez a virtual módosító az alaposztály metódusdeklarációjában használatos. A származtatott osztály ezután felülbírálhatja az alapszintű virtuális metódust a override kulcsszó használatával, vagy elrejtheti a virtuális metódust az alaposztályban a new kulcsszó használatával. Ha sem a override kulcsszó, sem a new kulcsszó nincs megadva, a fordító figyelmeztetést ad ki, és a származtatott osztály metódusa elrejti a metódust az alaposztályban.

Ennek a gyakorlatban való bemutatásához tegyük fel, hogy az A vállalat létrehozott egy osztályt GraphicsClass, amelyet a program használ. A következők:GraphicsClass

class GraphicsClass
{
    public virtual void DrawLine() { }
    public virtual void DrawPoint() { }
}

A vállalat ezt az osztályt használja, ön pedig saját osztályt hoz létre, új metódus hozzáadásával:

class YourDerivedGraphicsClass : GraphicsClass
{
    public void DrawRectangle() { }
}

Az alkalmazás problémamentesen használható, amíg az A vállalat nem ad ki egy új verziót GraphicsClass, amely a következő kódhoz hasonlít:

class GraphicsClass
{
    public virtual void DrawLine() { }
    public virtual void DrawPoint() { }
    public virtual void DrawRectangle() { }
}

Az új verzió GraphicsClass egy metódust DrawRectangletartalmaz. Kezdetben semmi sem történik. Az új verzió továbbra is binárisan kompatibilis a régi verzióval. Az üzembe helyezett szoftverek továbbra is működni fognak, még akkor is, ha az új osztály telepítve van ezeken a számítógépes rendszereken. A metódushoz DrawRectangle intézett összes meglévő hívás továbbra is hivatkozni fog az Ön verziójára a származtatott osztályban.

Amint azonban az alkalmazás újrafordítása az új verzió GraphicsClasshasználatával történik, figyelmeztetést kap a CS0108 fordítótól. Fontolja meg, hogyan szeretné, hogy a DrawRectangle metódus viselkedjen az alkalmazásában, amint az ebben a figyelmeztetésben szerepel.

Ha azt szeretné, hogy a metódus felülbírálja az új alaposztály-metódust, használja a következő kulcsszót override :

class YourDerivedGraphicsClass : GraphicsClass
{
    public override void DrawRectangle() { }
}

A override kulcsszó gondoskodik arról, hogy a származtatott YourDerivedGraphicsClass objektumok a származtatott osztályverziót DrawRectanglehasználják. A származtatott YourDerivedGraphicsClass objektumok továbbra is hozzáférhetnek az alaposztály verziójához DrawRectangle az alapszintű kulcsszó használatával:

base.DrawRectangle();

Ha nem szeretné, hogy a metódus felülbírálja az új alaposztály-metódust, az alábbi szempontokat kell figyelembe vennie. A két módszer közötti félreértések elkerülése érdekében átnevezheti a metódust. Ez időigényes és hibalehetőséget jelenthet, és bizonyos esetekben nem praktikus. Ha azonban a projekt viszonylag kicsi, a Visual Studio újrabontási beállításaival átnevezheti a metódust. További információ: Osztályok és típusok újrabontása (Osztálytervező).

Másik lehetőségként megakadályozhatja a figyelmeztetést a származtatott new osztálydefiníció kulcsszójának használatával:

class YourDerivedGraphicsClass : GraphicsClass
{
    public new void DrawRectangle() { }
}

new A kulcsszó használatával a fordító közli, hogy a definíció elrejti az alaposztályban található definíciót. Ez az alapértelmezett viselkedés.

Felülbírálás és metóduskiválasztás

Ha egy metódus el van nevezve egy osztályban, a C#-fordító kiválasztja a legjobban meghívható metódust, ha több metódus is kompatibilis a hívással, például ha két azonos nevű metódus van, és az átadott paraméterrel kompatibilis paraméterek. A következő módszerek kompatibilisek lehetnek:

public class Derived : Base
{
    public override void DoWork(int param) { }
    public void DoWork(double param) { }
}

Amikor a DoWork hívása megtörténik egy Derived példányon, a C# fordító először megpróbálja a hívást kompatibilissé tenni az eredetileg a DoWork-on deklarált Derived verziókkal. A felülbírálási metódusok nem minősülnek osztályon deklaráltnak, hanem egy alaposztályon deklarált metódus új implementációi. Csak akkor, ha a C#-fordító nem tudja a metódushívást illeszteni egy eredeti metódushoz Derived, akkor megpróbálja a hívást egy ugyanazzal a névvel és kompatibilis paraméterekkel rendelkező felülírt metódushoz illeszteni. Például:

int val = 5;
Derived d = new();
d.DoWork(val);  // Calls DoWork(double).

Mivel a val változót implicit módon lehet double típusra konvertálni, a C#-fordító a DoWork(double)-t hívja meg ahelyett, hogy a DoWork(int)-t hívná. Ezt kétféleképpen lehet elkerülni. Először is kerülje az új metódusok deklarálását a virtuális metódusokkal azonos néven. Másodszor utasíthatja a C#-fordítót, hogy hívja meg a virtuális metódust úgy, hogy az alaposztály metóduslistájában keres, ha a példányt a következőre DerivedállítjaBase. Mivel a metódus virtuális, a DoWork(int) végrehajtását Derived-on hívja meg a rendszer. Például:

((Base)d).DoWork(val);  // Calls DoWork(int) on Derived.

További példákat new és overridepéldákat a Felülbírálás és új kulcsszavak használatának ismerete című témakörben talál.

Lásd még