Die beiden Schlüsselwörter override und new werden in einer abgeleiteten Klasse angewendet um Methoden der Basisklasse zu überschreiben. Hierbei stellt sich die Frage warum es zwei verschiedene Schlüsselwörter gibt, wodurch diese sich unterscheiden und in welchen Fällen welches anzuwenden ist.
Override
Wenn die Methode der Basisklasse als virtuell markiert ist, dann muss das Überschreiben unter Angabe des override Schlüsselwortes erfolgen. Das folgende Beispiel zeigt eine entsprechende Implementierung.
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 MyChildClass myChild = new MyChildClass();
6
7 myChild.DoSomething();
8
9 Console.ReadKey();
10 }
11 }
12
13 public class MyBaseClass
14 {
15 public virtual void DoSomething()
16 {
17 Console.WriteLine("Base");
18 }
19 }
20
21 public class MyChildClass : MyBaseClass
22 {
23 public override void DoSomething()
24 {
25 base.DoSomething();
26 Console.WriteLine("Child");
27 }
28 }
Die Konsolenanwendung gibt „Base“ und „Child“ aus.
New
Bei Methoden die nicht virtuell sind, erfolgt das Überschreiben der Methode unter Angabe des Schlüsselwortes new.
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 MyChildClass myChild = new MyChildClass();
6
7 myChild.DoSomething();
8
9 Console.ReadKey();
10 }
11 }
12
13 public class MyBaseClass
14 {
15 public void DoSomething()
16 {
17 Console.WriteLine("Base");
18 }
19 }
20
21 public class MyChildClass : MyBaseClass
22 {
23 public new void DoSomething()
24 {
25 base.DoSomething();
26 Console.WriteLine("Child");
27 }
28 }
Die Konsolenanwendung gibt ebenfalls „Base“ und „Child“ aus.
Override vs. New
Die beiden Beispiele unterscheiden sich nicht nur in syntaktischer Hinsicht. Die Art des Aufrufes der Methoden unterscheidet sich wesentlich. Virtuelle Methoden werden dynamisch zur Laufzeit gebunden. Nicht virtuelle Methoden hingegen werden statisch zur Übersetzungszeit gebunden.
Dies lässt sich veranschaulichen indem ein cast auf das Objekt der Basisklasse erfolgt und von diesem Objekt aus der Methodenaufruf durchgeführt wird. Dazu wurde das erste Beispiel leicht modifiziert. In der Main Methode erfolgt der cast auf das Basisobjekt und der anschliessende Methodenaufruf.
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 MyChildClass myChild = new MyChildClass();
6 MyBaseClass myBase = myChild as MyBaseClass;
7
8 myBase.DoSomething();
9
10 Console.ReadKey();
11 }
12 }
13
14 public class MyBaseClass
15 {
16 public virtual void DoSomething()
17 {
18 Console.WriteLine("Base");
19 }
20 }
21
22 public class MyChildClass : MyBaseClass
23 {
24 public override void DoSomething()
25 {
26 base.DoSomething();
27 Console.WriteLine("Child");
28 }
29 }
Bei Ausführung dieser Anwendung wird dynamisch nach der entsprechenden Methode gesucht. Dies führt dazu das die abgeleitete Methode gesucht und gefunden wird. Trotz des cast auf die Basisklasse wird somit die Methode der abgeleiteten Klasse aufgerufen und die Konsolenanwendung gibt „Base“ und „Child“ aus.
Der Methodenaufruf mittels der Basisklasse wird im nachfolgenden Beispiel auf das Schlüsselwort new angewendet.
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 MyChildClass myChild = new MyChildClass();
6 MyBaseClass myBase = myChild as MyBaseClass;
7
8 myBase.DoSomething();
9
10 Console.ReadKey();
11 }
12 }
13
14 public class MyBaseClass
15 {
16 public void DoSomething()
17 {
18 Console.WriteLine("Base");
19 }
20 }
21
22 public class MyChildClass : MyBaseClass
23 {
24 public new void DoSomething()
25 {
26 base.DoSomething();
27 Console.WriteLine("Child");
28 }
29 }
In diesem Fall gibt die Konsolenanwendung nur „Base“ aus. Dies liegt daran, das die Methode nicht virtuell ist. Dadurch erfolgt eine statische Bindung und es wird nicht dynamisch nach Methoden in den abgeleiteten Klassen gesucht.
Fazit
Override und new werden zwar für den gleichen Zweck angewendet, für das Überschreiben von Methoden der Basisklasse, aber die beiden Aufrufe unterscheiden sich grundlegend im Hinblick auf die Art der Methodenbindung. Der Programmierer einer Klasse sollte je nach Anwendungsfall abwägen für welche Variante er sich entscheidet. Werden Methoden erstellt, die bewusst in abgeleiteten Klassen überschrieben werden sollen bzw. zumeist überschieben werden müssen, dann sollte die virtuelle Variante mittels der Schlüsselwörter virtual und override gewählt werden.