Tag 3 Unterricht und Aufgaben
This commit is contained in:
@@ -0,0 +1,339 @@
|
||||
# Vererbung, Überschreiben und Polymorphie in C#
|
||||
|
||||
## Ziel dieser Einheit
|
||||
|
||||
In dieser Einheit lernst du:
|
||||
|
||||
- was abstrakte Klassen sind
|
||||
- wie Vererbung in C# funktioniert
|
||||
- was der Unterschied zwischen `override` und `new` ist
|
||||
- wie Polymorphie funktioniert
|
||||
- warum Casting notwendig sein kann
|
||||
|
||||
---
|
||||
|
||||
## 1. Grundidee: Vererbung
|
||||
|
||||
Definition:
|
||||
|
||||
Klassen können von anderen Klassen erben.
|
||||
Dabei übernehmen sie Eigenschaften und Methoden.
|
||||
|
||||
Begriffe:
|
||||
- Basisklasse (Elternklasse)
|
||||
- Subklasse (Kindklasse)
|
||||
- Vererbung
|
||||
|
||||
---
|
||||
|
||||
## 2. Die Basisklasse: Krokodil
|
||||
|
||||
public abstract class Krokodil
|
||||
|
||||
Erläuterung:
|
||||
|
||||
- abstrakte Klasse → kann nicht instanziiert werden
|
||||
- dient als gemeinsame Grundlage
|
||||
|
||||
---
|
||||
|
||||
### Property
|
||||
|
||||
public string Farbe { get; private set; }
|
||||
|
||||
- Property mit unsichtbarem Backing-Field
|
||||
- Setter ist privat
|
||||
|
||||
---
|
||||
|
||||
### Konstruktoren
|
||||
|
||||
protected Krokodil() : this("Keine Farbe")
|
||||
|
||||
- Konstruktor-Verkettung mit `this`
|
||||
|
||||
protected Krokodil(string farbe)
|
||||
{
|
||||
Farbe = farbe;
|
||||
KrokodilListe.Add(this);
|
||||
}
|
||||
|
||||
- jedes Objekt wird automatisch in eine Liste eingefügt
|
||||
|
||||
---
|
||||
|
||||
### Abstrakte Methode
|
||||
|
||||
public abstract void ZeigeInfoZumLebensraum();
|
||||
|
||||
Erläuterung:
|
||||
|
||||
- muss in allen Unterklassen implementiert werden
|
||||
|
||||
---
|
||||
|
||||
### Virtuelle Methode
|
||||
|
||||
public virtual void Schwimmen()
|
||||
{
|
||||
Console.WriteLine("Ich schwimme im Wasser.");
|
||||
}
|
||||
|
||||
Erläuterung:
|
||||
|
||||
- kann überschrieben werden
|
||||
- muss aber nicht
|
||||
|
||||
---
|
||||
|
||||
## 3. Klasse Leistenkrokodil
|
||||
|
||||
public sealed class Leistenkrokodil : Krokodil
|
||||
|
||||
Erläuterung:
|
||||
|
||||
- `sealed` → keine weitere Vererbung möglich
|
||||
|
||||
---
|
||||
|
||||
### Überschreiben abstrakter Methoden
|
||||
|
||||
public override void ZeigeInfoZumLebensraum()
|
||||
|
||||
Erläuterung:
|
||||
|
||||
- `override` ist verpflichtend
|
||||
- Verhalten wird neu definiert
|
||||
|
||||
---
|
||||
|
||||
### Überschreiben virtueller Methoden
|
||||
|
||||
public override void Schwimmen()
|
||||
{
|
||||
base.Schwimmen();
|
||||
Console.WriteLine("Ich schwimme im Salzwasser.");
|
||||
}
|
||||
|
||||
Erläuterung:
|
||||
|
||||
- `base` greift auf Verhalten der Basisklasse zu
|
||||
|
||||
---
|
||||
|
||||
### Eigene Methode
|
||||
|
||||
public void ImSchlammLiegen()
|
||||
|
||||
- nur in dieser Klasse verfügbar
|
||||
|
||||
---
|
||||
|
||||
## 4. Klasse Nilkrokodil
|
||||
|
||||
public class Nilkrokodil : Krokodil
|
||||
|
||||
---
|
||||
|
||||
### Überschreiben mit sealed
|
||||
|
||||
public sealed override void ZeigeInfoZumLebensraum()
|
||||
|
||||
- verhindert weiteres Überschreiben
|
||||
|
||||
---
|
||||
|
||||
### Methode mit new
|
||||
|
||||
public new void Schwimmen()
|
||||
|
||||
Erläuterung:
|
||||
|
||||
- `new` blendet die Methode aus
|
||||
- kein echtes Überschreiben
|
||||
|
||||
---
|
||||
|
||||
### Eigene Methode
|
||||
|
||||
public void ImGrasLiegen()
|
||||
|
||||
---
|
||||
|
||||
### Property mit new
|
||||
|
||||
public new string Farbe => base.Farbe.ToUpper();
|
||||
|
||||
Erläuterung:
|
||||
|
||||
- Getter wurde neu definiert
|
||||
- gibt Wert in Großbuchstaben zurück
|
||||
- Expression Bodied Member
|
||||
|
||||
---
|
||||
|
||||
## 5. Anwendung in der Main-Methode
|
||||
|
||||
Leistenkrokodil leistenkrokodil = new Leistenkrokodil("...");
|
||||
|
||||
Console.WriteLine($"Farbe des Krokodils: {leistenkrokodil.Farbe}");
|
||||
|
||||
---
|
||||
|
||||
### Methodenaufrufe
|
||||
|
||||
leistenkrokodil.ZeigeInfoZumLebensraum();
|
||||
leistenkrokodil.Schwimmen();
|
||||
leistenkrokodil.ImSchlammLiegen();
|
||||
|
||||
- implementierte Methode
|
||||
- überschriebene Methode
|
||||
- eigene Methode
|
||||
|
||||
---
|
||||
|
||||
### Nilkrokodil
|
||||
|
||||
Nilkrokodil nilkrokodil = new Nilkrokodil("...");
|
||||
|
||||
Console.WriteLine($"Farbe des Krokodils: {nilkrokodil.Farbe}");
|
||||
|
||||
---
|
||||
|
||||
### Verhalten von new
|
||||
|
||||
nilkrokodil.Schwimmen();
|
||||
|
||||
- kein Unterschied sichtbar bei direkter Verwendung
|
||||
|
||||
---
|
||||
|
||||
## 6. Polymorphie mit Basisklasse
|
||||
|
||||
foreach (Krokodil k in Krokodil.KrokodilListe)
|
||||
|
||||
---
|
||||
|
||||
### Reflection
|
||||
|
||||
Console.WriteLine(k.GetType().Name);
|
||||
|
||||
- tatsächlicher Typ zur Laufzeit
|
||||
|
||||
---
|
||||
|
||||
### Verhalten von override
|
||||
|
||||
k.ZeigeInfoZumLebensraum();
|
||||
|
||||
- abhängig von der Subklasse
|
||||
|
||||
---
|
||||
|
||||
### Verhalten von new
|
||||
|
||||
Console.WriteLine(k.Farbe);
|
||||
|
||||
Erläuterung:
|
||||
|
||||
- nur Basisklassen-Version wird verwendet
|
||||
- `new` greift hier nicht
|
||||
|
||||
---
|
||||
|
||||
### Unterschied sichtbar machen
|
||||
|
||||
k.Schwimmen();
|
||||
|
||||
- einmal überschrieben
|
||||
- einmal nur ausgeblendet
|
||||
|
||||
---
|
||||
|
||||
## 7. Casting
|
||||
|
||||
### Direktes Casting
|
||||
|
||||
((Leistenkrokodil)k).ImSchlammLiegen();
|
||||
|
||||
- kann Exception werfen
|
||||
|
||||
---
|
||||
|
||||
### Sicheres Casting mit as
|
||||
|
||||
(k as Nilkrokodil)?.ImGrasLiegen();
|
||||
|
||||
- gibt null zurück
|
||||
- `?` prüft auf null
|
||||
|
||||
---
|
||||
|
||||
### Casting mit is
|
||||
|
||||
if (k is Leistenkrokodil l)
|
||||
l.ImSchlammLiegen();
|
||||
|
||||
---
|
||||
|
||||
if (k is Nilkrokodil n)
|
||||
{
|
||||
n.ImGrasLiegen();
|
||||
n.Schwimmen();
|
||||
}
|
||||
|
||||
- kombiniert Typprüfung und Casting
|
||||
|
||||
---
|
||||
|
||||
## 8. Wichtige Konzepte im Überblick
|
||||
|
||||
### abstract
|
||||
- MUSS überschrieben werden
|
||||
|
||||
---
|
||||
|
||||
### virtual
|
||||
- KANN überschrieben werden
|
||||
|
||||
---
|
||||
|
||||
### override
|
||||
- echtes Überschreiben
|
||||
|
||||
---
|
||||
|
||||
### new
|
||||
- nur Ausblenden
|
||||
|
||||
---
|
||||
|
||||
### sealed
|
||||
- verhindert weiteres Überschreiben
|
||||
|
||||
---
|
||||
|
||||
### Polymorphie
|
||||
- Verhalten abhängig vom tatsächlichen Objekttyp
|
||||
|
||||
---
|
||||
|
||||
## Zusammenfassung
|
||||
|
||||
- Vererbung ermöglicht Wiederverwendung von Code
|
||||
- abstrakte Methoden müssen implementiert werden
|
||||
- virtuelle Methoden können überschrieben werden
|
||||
- `override` und `new` verhalten sich unterschiedlich
|
||||
- Polymorphie bestimmt das Verhalten zur Laufzeit
|
||||
- Casting ist notwendig für Zugriff auf Subklassen
|
||||
|
||||
---
|
||||
|
||||
## Verständnisfragen
|
||||
|
||||
- Was ist der Unterschied zwischen `override` und `new`?
|
||||
- Wann wird eine Methode überschrieben?
|
||||
- Warum funktioniert `new` bei Polymorphie anders?
|
||||
- Wann ist Casting notwendig?
|
||||
- Was macht `sealed`?
|
||||
``
|
||||
Reference in New Issue
Block a user