Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lernen Polymorphismus | OOP-Prinzipien
C# Über die Grundlagen Hinaus
course content

Kursinhalt

C# Über die Grundlagen Hinaus

C# Über die Grundlagen Hinaus

1. Zusätzliche Strukturen & Dateiverarbeitung
2. Strukturen & Enumeratoren
3. Einführung in die Objektorientierte Programmierung (OOP)
4. OOP Essentials
5. OOP-Prinzipien

book
Polymorphismus

Der Begriff Polymorphismus bedeutet "in mehreren verschiedenen Formen auftreten". Im Kontext der objektorientierten Programmierung bezieht sich Polymorphismus auf die Fähigkeit einer Klasse, eine gemeinsame Schnittstelle für ihre abgeleiteten Klassen bereitzustellen, während jede abgeleitete Klasse spezifische Verhaltensweisen für die geerbten Methoden implementieren kann.

Normalerweise, wenn wir ein Objekt einer Klasse erstellen, erstellen wir eine Variable, um die Referenz dieses Objekts zu halten. Und der Typ der Variable ist normalerweise die Klasse dieses Objekts.

Zum Beispiel:

cs

index

copy
123
Dog myVar = new Dog(); // or even in case of implicit declaration, 'myVar' will be of type 'Dog' var myVar = new Dog();

Wir können jedoch auch eine Variable einer Basisklasse erstellen und ein Objekt einer abgeleiteten Klasse darin speichern.

Zum Beispiel:

cs

index

copy
1234567891011121314151617181920212223242526272829303132
using System; class Mammal { public int age; public Mammal(int age) { this.age = age; } } class Dog : Mammal { public string breed; public Dog(int age, string breed) : base(age) { this.breed = breed; } } class ConsoleApp { static void Main() { Mammal example = new Dog(10, "Labrador"); Console.WriteLine(example.age); Console.WriteLine(example.breed); // Error because it's not accessible (read explanation below) } }

Das breed-Attribut des Dog-Objekts ist nicht zugänglich, weil wenn wir das Dog-Objekt in eine Mammal-Variable speichern, es implizit in Mammal umgewandelt wird. Das bedeutet, dass wir nur auf die Attribute und Methoden zugreifen können, die in der Mammal-Klasse vorhanden sind. Es bedeutet nicht, dass der Wert, der in der breed-Klasse gespeichert ist, verloren geht, er ist nur unzugänglich und wir können sagen, dass er im Wesentlichen versteckt ist.

Wir können example einfach durch explizites Typcasting in einen Dog umwandeln und das breed-Attribut wird wieder verfügbar:

cs

index

copy
12345678910111213141516171819202122232425262728293031323334353637383940
using System; class Mammal { public int age; public Mammal(int age) { this.age = age; } public void speak() { // Empty for now } } class Dog : Mammal { public string breed; public Dog(int age, string breed) : base(age) { this.breed = breed; } } class ConsoleApp { static void Main() { Mammal example = new Dog(10, "Labrador"); Console.WriteLine(example.age); Dog casted = (Dog)example; Console.WriteLine(casted.breed); } }

Für Methoden gibt es jedoch eine zusätzliche Funktion namens Methodenüberschreibung, die der Methodenüberladung etwas ähnlich ist. Dabei definieren wir eine Methode aus einer Basisklasse in der abgeleiteten Klasse im Wesentlichen neu.

Zum Beispiel möchten wir, dass Mammal eine Methode speak() hat, die Woof! ausgibt, wenn sie von einem Dog-Objekt aufgerufen wird, und Meow!, wenn sie von einem Cat-Objekt aufgerufen wird:

cs

index

copy
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
using System; class Mammal { public void speak() { Console.WriteLine("Mammal Speaks"); } } class Dog : Mammal { public void speak() { Console.WriteLine("Woof!"); } } class Cat : Mammal { public void speak() { Console.WriteLine("Meow!"); } } class ConsoleApp { static void Main() { // The following execute the overriden version of the methods Dog d1 = new Dog(); d1.speak(); Cat c1 = new Cat(); c1.speak(); Mammal m1 = new Mammal(); Mammal m2 = new Cat(); Mammal m3 = new Dog(); // All of these execute the 'Mammal' version of the method m1.speak(); m2.speak(); m3.speak(); } }

Die Warnungen, die wir bei dieser Kompilierung erhalten, sind auf überlappende Namen von Methoden in Eltern- und Kindklassen zurückzuführen. In diesem Fall gibt es eine Überlappung zwischen den speak-Methoden der Klassen Cat und Mammal sowie zwischen Dog und Mammal, weshalb wir zwei Warnungen erhalten.

Beachten Sie jedoch am Ende, wie m1, m2 und m3 die in der Mammal-Klasse definierte Methode ausführen. Dies liegt daran, dass sie in Mammal-Objekte umgewandelt werden.

Wenn wir möchten, dass sich die speak-Methode so verhält, wie sie es in ihrem ursprünglichen Objekt tut, können wir sie einfach in eine virtuelle Methode umwandeln. Eine virtuelle Methode ist einfach eine Methode, die es uns ermöglicht, sich von abgeleiteten Klassen selbst zu überschreiben, sodass die spezifische Implementierung zur Laufzeit basierend auf dem Typ des ursprünglichen Objekts bestimmt wird.

Um eine Methode virtuell zu machen, fügen wir einfach das Schlüsselwort virtual vor ihrem Rückgabetyp hinzu:

cs

index

copy
1234567
class Mammal { public virtual void speak() { Console.WriteLine("Mammal Speaks"); } }

Um eine überschreibene Implementierung dieser Methode zu erstellen, verwenden wir das Schlüsselwort override vor dem Rückgabetyp in der Implementierung der abgeleiteten Klasse dieser neuen Implementierung:

cs

index

copy
123456789101112131415
class Dog : Mammal { public override void speak() { Console.WriteLine("Woof!"); } } class Cat : Mammal { public override void speak() { Console.WriteLine("Meow!"); } }

Lassen Sie uns nun die beiden Code-Snippets zusammenfügen und sehen, wie sich dies auf die Ausgabe auswirkt:

cs

index

copy
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
using System; class Mammal { public virtual void speak() { Console.WriteLine("Mammal Speaks"); } } class Dog : Mammal { public override void speak() { Console.WriteLine("Woof!"); } } class Cat : Mammal { public override void speak() { Console.WriteLine("Meow!"); } } class ConsoleApp { static void Main() { Mammal m1 = new Mammal(); Mammal m2 = new Cat(); Mammal m3 = new Dog(); m1.speak(); // Since it stores a Mammal() object, it executes the Mammal's implementation m2.speak(); // Output: Meow! m3.speak(); // Output: Woof! // The following behave the same as they did in the previous example: Dog d1 = new Dog(); d1.speak(); Cat c1 = new Cat(); c1.speak(); } }

Sie sehen, dass im Output m2 und m3 die Implementierung der Methode von Cat und Dog verwenden, weil diese Objekte ursprünglich Cat und Dog waren. Dieser gesamte Prozess des Überschreibens von Methoden, sodass sie sich basierend auf ihrem ursprünglichen Typ verhalten, wird als Polymorphismus bezeichnet.

Eine Situation, in der dies sehr nützlich sein kann, ist die Möglichkeit, Objekte von mehreren verschiedenen Datentypen in einem einzigen Array oder einer Liste zu speichern.

Zum Beispiel:

cs

index

copy
123456789
List<Shape> shapes = new List<Shape>(); shapes.Add(new Rectangle(25, 50)); shapes.Add(new Square(50)); shapes.Add(new Circle(10)); shapes[0].getArea(); // Output: 1250.0f shapes[1].getArea(); // Output: 2500.0f shapes[2].getArea(); // Output: 314.15f

1. Welche zwei Schlüsselwörter werden beim Überschreiben von Methoden verwendet?

2. Was ist der korrekte Weg, um eine Methode überschreibbar zu machen?

Welche zwei Schlüsselwörter werden beim Überschreiben von Methoden verwendet?

Welche zwei Schlüsselwörter werden beim Überschreiben von Methoden verwendet?

Wählen Sie die richtige Antwort aus

Was ist der korrekte Weg, um eine Methode überschreibbar zu machen?

Was ist der korrekte Weg, um eine Methode überschreibbar zu machen?

Wählen Sie die richtige Antwort aus

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 5. Kapitel 4
We're sorry to hear that something went wrong. What happened?
some-alt