Klasa może dziedziczyć (bezpośrednio) tylko z jednej nadklasy.
Jednak każda klasa (a także struktura i interfejs) może implementować
wiele interfejsów. Na szczycie hierarchii dziedziczenia
znajduje się klasa object
, po której niejawnie dziedziczą
wszystkie klasy i struktury. Przykładowo:
class Przykład2 : Przykład { // <- Klasa Przykład2 jawnie
... // dziedzicząca z klasy Przykład
public Przykład2( ) : base(1) { // <- Konstruktor, który jawnie
} // wywołuje konstruktor nadklasy
}
Klasa B dziedzicząca z klasy A może być niejawnie rzutowana (w górę hierarchii) do klasy A. Natomiast klasa A może być jawnie rzutowana (w dół hierarchii) do klasy B (w przypadku niepowodzenia jest zgłaszany wyjątek InvalidCastException ).
is : operator pozwalający sprawdzić czy obiekt należy
do danej klasy, np.
if(p is Przykład2){...} // Sprawdza czy p wskazuje na obiekt typu Przykład2
as : operator pozwalający rzutować w dół w taki sposób, że gdy rzutowanie nie powiedzie się zwracane jest null (a nie rzucany wyjątek), np.
Przykład p;
Przykład2 p2;
p2= p as Przykład2;
Oznaczając metodę jako wirtualną wskazujemy, że może ona (ale nie musi) być zrealizowana jeszcze raz w klasach pochodnych. Przed każdym wywołaniem takiej funkcji musi zostać sprawdzony rzeczywisty typ obiektu, na rzecz którego jest ona wywoływana (Zostanie wywołana funkcja właściwa dla obiektu - nawet jeśli wskazujemy na niego referencją klasy podstawowej. Gdyby funkcja nie była wirtualna, została by po prostu wywołana funkcja odpowiednia dla typu, jakiego jest sama referencja - bez sprawdzania typu obiektu).
virtual : słowo kluczowe pozwalające zadeklarować funkcję (w klasie bazowej) jako wirtualną
override : słowo kluczowe pozwalające na przesłonięcie (w klasie pochodnej) funkcji wirtualnej.
Przykład:
class A {
public virtual void wypiszNazwę( ) {
System.Console.Write("A");
}
}
class B : A { // Klasa B dziedzicząca z klasy A
public override void wypiszNazwę( ) {
System.Console.Write("B");
}
}
... // W tym kodzie operacja a.wypiszNazwę() wypisze na ekranie "B",
A a = new B( ) ; // gdyż a wskazuje na obiekt klasy B (gdyby wipiszNazwę nie była
a.wypiszNazwę( ); // funkcją wirtualną wypisała by "A" ).
...
abstract : słowo kluczowe pozwalające zadeklarować klasę / metodę jako abstrakcyjną.
Metody abstrakcyjne są funkcjami nie posiadającymi implementacji i z założenia są wirtualne (gdyż będą przesłaniane w klasach pochodnych). Klasa abstrakcyjna może posiadać metody abstrakcyjne. Klasa pochodna od klasy abstrakcyjnej musi przesłaniać wszystkie jej metody abstrakcyjne lub sama musi być klasą abstrakcyjną.
Np.
abstract class A { // Klasa abstrakcyjna
public abstract void jakaśFunkcja( ) ; // Metoda abstrakcyjna
}