Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Język C# został zaprojektowany tak, aby zarządzanie wersjami między klasami podstawowymi i pochodnymi w różnych bibliotekach mogło ewoluować i zachowywać zgodność wsteczną. Oznacza to na przykład, że wprowadzenie nowego elementu członkowskiego w klasie bazowej o takiej samej nazwie jak składowa w klasie pochodnej jest całkowicie obsługiwane przez język C# i nie prowadzi do nieoczekiwanego zachowania. Oznacza to również, że klasa musi jawnie określić, czy metoda ma zastąpić dziedziczonej metody, czy też metoda jest nową metodą, która ukrywa metodę o podobnej nazwie dziedziczonej.
W języku C#klasy pochodne mogą zawierać metody o tej samej nazwie co metody klasy bazowej.
Jeśli metoda w klasie pochodnej nie jest poprzedzona nowymi lub zastępowanymi słowami kluczowymi, kompilator wyda ostrzeżenie, a metoda będzie zachowywać się tak, jakby
newsłowo kluczowe było obecne.Jeśli metoda w klasie pochodnej jest poprzedzona
newsłowem kluczowym, metoda jest definiowana jako niezależna od metody w klasie bazowej.Jeśli metoda w klasie pochodnej jest poprzedzona
overridesłowem kluczowym, obiekty klasy pochodnej wywołają tę metodę zamiast metody bazowej.Aby użyć słowa kluczowego
overridedo metody w klasie pochodnej, metoda klasy bazowej musi zostać zdefiniowana jako virtual.Metodę klasy bazowej można wywołać z klasy pochodnej przy użyciu słowa kluczowego
base.Słowa
overridekluczowe ,virtualinewmożna również stosować do właściwości, indeksatorów i zdarzeń.
Domyślnie metody języka C# nie są wirtualne. Jeśli metoda jest zadeklarowana jako wirtualna, każda klasa dziedzicząca metodę może zaimplementować własną wersję. Aby utworzyć metodę wirtualną, virtual modyfikator jest używany w deklaracji metody klasy bazowej. Klasa pochodna może następnie zastąpić podstawową metodę wirtualną za pomocą override słowa kluczowego lub ukryć metodę wirtualną w klasie bazowej przy użyciu słowa kluczowego new . Jeśli nie zostanie określone ani słowo kluczowe override, ani new słowo kluczowe, kompilator wyświetli ostrzeżenie, a metoda w klasie pochodnej ukryje metodę w klasie bazowej.
Aby to zademonstrować w praktyce, załóżmy na chwilę, że firma A utworzyła klasę o nazwie GraphicsClass, której używa program. Poniżej przedstawiono następujące elementy:GraphicsClass
class GraphicsClass
{
public virtual void DrawLine() { }
public virtual void DrawPoint() { }
}
Firma używa tej klasy i używa jej do utworzenia własnej klasy, dodając nową metodę:
class YourDerivedGraphicsClass : GraphicsClass
{
public void DrawRectangle() { }
}
Aplikacja jest używana bez problemów, dopóki firma A nie wyda nowej wersji GraphicsClassprogramu , która przypomina następujący kod:
class GraphicsClass
{
public virtual void DrawLine() { }
public virtual void DrawPoint() { }
public virtual void DrawRectangle() { }
}
Nowa wersja programu GraphicsClass zawiera teraz metodę o nazwie DrawRectangle. Początkowo nic się nie dzieje. Nowa wersja jest nadal binarna zgodna ze starą wersją. Wszelkie wdrożone oprogramowanie będzie nadal działać, nawet jeśli nowa klasa jest zainstalowana w tych systemach komputerowych. Wszystkie istniejące wywołania metody DrawRectangle będą nadal odwoływać się do twojej wersji w klasie pochodnej.
Jednak po ponownym skompilowaniu aplikacji przy użyciu nowej wersji GraphicsClassprogramu zostanie wyświetlone ostrzeżenie kompilatora CS0108. To ostrzeżenie informuje, że musisz rozważyć, jak metoda DrawRectangle powinna się zachowywać w kontekście aplikacji.
Jeśli chcesz, aby metoda przesłoniła nową metodę klasy bazowej, użyj słowa kluczowego override :
class YourDerivedGraphicsClass : GraphicsClass
{
public override void DrawRectangle() { }
}
Słowo override kluczowe zapewnia, że wszystkie obiekty pochodzące z YourDerivedGraphicsClass klasy będą używać pochodnej DrawRectanglewersji klasy . Obiekty pochodzące z YourDerivedGraphicsClass mogą nadal uzyskiwać dostęp do wersji DrawRectangle klasy bazowej przy użyciu słowa kluczowego base:
base.DrawRectangle();
Jeśli nie chcesz, aby metoda przesłoniła nową metodę klasy bazowej, należy wziąć pod uwagę następujące zagadnienia. Aby uniknąć nieporozumień między dwiema metodami, możesz zmienić nazwę metody. Może to być czasochłonne i podatne na błędy, a po prostu nie jest praktyczne w niektórych przypadkach. Jeśli jednak projekt jest stosunkowo mały, możesz użyć opcji refaktoryzacji programu Visual Studio, aby zmienić nazwę metody. Aby uzyskać więcej informacji, zobacz Refaktoryzacja klas i typów (Projektant klas).
Alternatywnie możesz zapobiec ostrzeżeniu, używając słowa kluczowego new w definicji klasy pochodnej:
class YourDerivedGraphicsClass : GraphicsClass
{
public new void DrawRectangle() { }
}
Użycie słowa kluczowego new informuje kompilator, że definicja ukrywa definicję zawartą w klasie bazowej. Jest to zachowanie domyślne.
Zastępowanie i wybór metody
Gdy metoda ma nazwę w klasie, kompilator języka C# wybiera najlepszą metodę do wywołania, jeśli więcej niż jedna metoda jest zgodna z wywołaniem, na przykład gdy istnieją dwie metody o tej samej nazwie i parametry zgodne z przekazanym parametrem. Następujące metody byłyby zgodne:
public class Derived : Base
{
public override void DoWork(int param) { }
public void DoWork(double param) { }
}
Po wywołaniu DoWork w instancji Derived, kompilator języka C# najpierw spróbuje wykonać wywołanie zgodne z wersjami DoWork zadeklarowanymi pierwotnie w Derived. Metody przesłonięcia nie są uznawane za zadeklarowane w klasie. Są to nowe implementacje metody zadeklarowanej w klasie bazowej. Tylko wtedy, gdy kompilator języka C# nie może dopasować wywołania metody do oryginalnej metody w systemie Derived, spróbuje dopasować wywołanie metody do metody przesłoniętej o tej samej nazwie i zgodnych parametrach. Na przykład:
int val = 5;
Derived d = new();
d.DoWork(val); // Calls DoWork(double).
Ponieważ zmienną val można niejawnie przekonwertować na typ double, kompilator języka C# wywołuje DoWork(double) zamiast DoWork(int). Istnieją dwa sposoby, aby tego uniknąć. Najpierw należy unikać deklarowania nowych metod o tej samej nazwie co metody wirtualne. Po drugie, można poinstruować kompilator języka C#, aby wywołał metodę wirtualną, przeszukując listę metod klasy bazowej poprzez rzutowanie wystąpienia Derived do klasy Base. Ponieważ metoda jest wirtualna, zostanie wywołana implementacja DoWork(int) na Derived. Na przykład:
((Base)d).DoWork(val); // Calls DoWork(int) on Derived.
Aby uzyskać więcej przykładów elementów new i override, zobacz Wiedza o tym, kiedy używać przesłonięć i nowych słów kluczowych.