Metoda wirtualna:
- oznaczona słowem kluczowym
virtual
- włącza mechanizm polimorfizmu dynamicznego
- tworzymy ją w klasie bazowej
- w klasach pochodnych przesłaniamy metody wirtualne za pomocą słowa kluczowego
override
- przesłonięcie nie jest obowiązkowe, w razie jego braku zostanie wywołana metoda klasy bazowej
- metody statyczne ani prywatne nie mogą być wirtualne
- metody, które nie są wirtualne, nie można przesłonić za pomocą
override
Przykład:
class Pojazd
{
public virtual void Jedz() { Console.WriteLine("Jadę pojazdem"); }
}
class Samochod : Pojazd
{
public override void Jedz() { Console.WriteLine("Jadę samochodem"); }
}
Kod w Main
:
Pojazd p1 = new Pojazd();
p1.Jedz();
Samochod s1 = new Samochod();
s1.Jedz();
Pojazd sp1 = new Samochod();
sp1.Jedz();
Po co?
- dajemy informację dla innej osoby zajmującej się kodem
- przy tworzeniu klasy potomnych mamy elastyczność: możemy zostawić to jak jest w klasie bazowej lub przesłonić
Metody wirtualne w klasie Object
:
- w C# każda klasa (niedziedzicząca po innej) dziedziczy niejawnie z klasy
Object
.
public class Object
{
/* składowe wirtualne */
virtual public bool Equals(object o);
virtual protected void Finalize();
virtual public string ToString();
/* itp.. */
}
Metody abstrakcyjne:
- poprzedzone słowem kluczowym
abstract
- nie zawierają ciała metody (podobnie jak przy interfejsach)
- mogą być zadeklarowane tylko w klasie abstrakcyjnej (poprzedzonej słowem
abstract
)
Klasa abstrakcyjna
- poprzedzona słowem
abstract
- nie możemy stworzyć egzemplarza (obiektu) klasy abstrakcyjnej (podobnie jak przy interfejsach), ale możemy dziedziczyć po klasie abstrakcyjnej
- klasa abstrakcyjna może posiadać zwykłe metody (z implementacją)
- klasa pochodna do klasy abstrakcyjnej musi przesłonić wszystkie metody abstrakcyjne
abstract class Pojazd
{
public abstract void Jedz();
}
class Samochod : Pojazd
{
public override void Jedz() { Console.WriteLine("Jadę samochodem"); }
}
class Rower : Pojazd
{
public override void Jedz() { Console.WriteLine("Jadę rowerem"); }
}
Wirtualne czy abstrakcyjne?
- wirtualne: tam gdzie może dojść do powielenia kodu w klasie potomnej, chcemy stworzyć obiekty klasy bazowej
- abstrakcyjne: w sytuacjach gdy nie powielamy kodu, tworzenie obiektów klasy bazowej nie ma sensu