New versus Virtual

C# jest językiem obiektowym, czyli możemy w nim między innymi korzystać z mechanizmu polimorfizmu. Aby to zrobić wystarczy oznaczyć funkcje w klasie bazowej słowem kluczowym virtual. A następnie w klasie dziedziczącej nadpisać metodę za pomocą słowa kluczowego override. Tak jak to widać niżej na listingu:

   1: public class BaseClass
   2: {
   3:     public virtual void Execute()
   4:     {
   5:         Console.WriteLine("BaseClass.Execute");
   6:     }
   7: }
   8:  
   9: public class OverriderClass : BaseClass
  10: {
  11:     public override void Execute()
  12:     {
  13:         Console.WriteLine("OverriderClass.Execute");
  14:     }
  15: }

Wykonanie następującego kodu:

   1: OverriderClass overriderClass = new OverriderClass();
   2: BaseClass baseClass = overriderClass;
   3: overriderClass.Execute();
   4: baseClass.Execute();

Spowoduje wyświetlenie:

   1: OverriderClass.Execute
   2: OverriderClass.Execute

Czego myślę każdy się spodziewał. Wywołana została metoda, najbardziej pasującą do obiektu, na którego wskazują referencje.

Co natomiast stanie się, gdy usuniemy słowo kluczowe override? Wyświetli się coś takiego:

   1: OverriderClass.Execute
   2: BaseClass.Execute

Czyli nie mamy tutaj już do czynienia z polimorfizmem, tylko wywoływana jest metoda zależna od typu referencji, a nie obiektów, na który wskazuje referencja.

Co ciekawego możemy zobaczyć, to informacja jaką podczas kompilacji zwraca nam Visual Studio. Dokładnie treść ostrzeżenia: “OverriderClass.Execute() hides inherited member BaseClass.Execute(). To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.”

Visual Studio mówi nam w ostrzeżeniu, że jeśli chcemy skorzystać z polimorfizmu to powinniśmy użyć słowa kluczowego override. Natomiast jeśli świadomie chcemy nie korzystać z polimorfizmu i przykryć implementacje metody Execute, powinniśmy użyć słowa kluczowego new, aby dać kompilatorowi znać, że chcemy tak zrobić. Gdy nie podamy żadnego słowa kluczowego, kompilator zachowa się tak, jakbyśmy użyli słowa kluczowego new. Z tym wyjątkiem, że wygeneruje powyższy błąd.

Przy tym zagadnieniu wyraźnie widać jedną z różnic między c# a java. W javie wszystkie metody są domyślnie virtualne. W c# jest na odwrót.

Tags: , ,
Categories: Techniczne

Permalink E-mail | Kick it! | DZone it! | del.icio.us Komentarze (0) Post RSSRSS comment feed

Dodaj komentarz


(Będzie pokazywało Gravatar ikon)

  Country flag

biuquote
  • Komentarz
  • Przegląd
Loading