Definition Felder Konstruktor Methoden Beispiel Vererbung Definition Felder Konstruktor Methoden Beispiel Dr. Beatrice Amrhein
Definition
Definition: Vererbung Die Vererbung dient dazu, mit Hilfe von existierenden Klassen neue Klassen zu implementieren. Die neue Klasse erhält dabei (Zugriff auf) alle Felder und Methoden der Basisklasse, die nicht private sind.
Vererbung: Schreibweise Die Deklaration der abgeleiteten Klasse hängt den Namen der Basisklasse mit einem Doppelpunkt an. class AbgeleiteteKlasse : BasisKlasse { . . . } Dadurch erhält die abgeleiteten Klasse alle Methoden und Felder der Basisklasse (ausser denen, die private sind).
Beispiel Die Basisklasse hat zum Beispiel ein Feld und eine Methode class BasisKlasse { protected int feld = 2; protected int Methode1(int a) return a + feld; } Die abgeleitete Klasse «erbt» alle Felder und Methoden und kann diese benutzen. class AbgeleiteteKlasse : BasisKlasse public float Methode2(float a) return a + feld + Methode1(5);
protected Der Modifizierer protected bedeutet, dass nur die (Basis-)Klasse und die davon abgeleiteten Klassen dieses Feld, diesen Konstruktor oder diese Methode sehen (oder benutzen) können. class BasisKlasse { // Felder protected int feld1; // Konstuktor protected int BasisKlasse(int a) { feld1 = a; } // Methoden protected int Methode1(int a) { return a + feld; } } In diesem Beispiel kann nur die BasisKlasse und alle davon abgeleiteten Klassen das feld1 und die Methode1 sehen und benutzen. Der protected Konstuktor kann nur von den abgeleiteten Klassen aufgerufen werden.
Felder
Vererbte Felder Jedes nicht private Feld, welches in der Basisklasse deklariert (und initialisiert) wird, existiert auch in der abgeleiteten Klasse. class BasisKlasse { protected String name = "Hase"; protected double feld = 1.41; } class AbgeleiteteKlasse : BasisKlasse public double Methode(double a) Console.WriteLine(name); return a + feld; Inhalt von name = Hase Wert von feld = 1.41
Vererbte Felder Zur besseren Erkennung, woher das Feld stammt, kann jeweils mit den Schlüsselwörtern this und base gearbeitet werden class BasisKlasse { protected double feld1 = 1.41; } class AbgeleiteteKlasse : BasisKlasse private int feld2 = 4; public double Methode(double a) return a + base.feld1 + this.feld2; base this
Vererbte const Felder Auch die konstanten Felder werden vererbt class BasisKlasse { protected const String name = "Hase"; protected double feld1 = 1.41; } class AbgeleiteteKlasse : BasisKlasse private int feld2 = 4; public double Methode(double a) Console.WriteLine(BasisKlasse.name); Console.WriteLine(AbgeleiteteKlasse.name); return a + base.feld1 + this.feld2; name ist das gleiche Feld, in der Basis- und in der abgeleiteten Klasse
Konstruktor
Konstruktor Der Konstruktor der Basisklasse wird in der abgeleiteten Klasse durch den Aufruf base(args) aufgerufen. class BasisKlasse { protected double feld1; protected BasisKlasse( double d ) { this.feld1 = d; } } class AbgeleiteteKlasse : BasisKlasse private int feld2; public AbgeleiteteKlasse(double d, int e) : base(d) { this.feld2 = e; } public double Methode(double a) { return base.feld1 + this.feld2; } Konstruktor der Basisklasse aufrufen -> Wert d an feld1 zuweisen
Konstruktor ohne Argumente Der Konstruktor der Basisklasse ohne Argumente wird in der abgeleiteten Klasse durch den Aufruf base() aufgerufen. class BasisKlasse { protected double feld1; protected BasisKlasse( ) { this.feld1 = 5; } } class AbgeleiteteKlasse : BasisKlasse private int feld2; public AbgeleiteteKlasse(double d, int e) : base() { this.feld2 = e; } public double Methode(double a) { return base.feld1 + this.feld2; } Konstruktor der Basisklasse aufrufen
Konstruktor ohne Argumente Falls der Konstruktor der Basisklasse keine Argumente hat, kann der Aufruf base() weggelassen werden, da der Konstruktor der Basisklasse im Konstuktor der abgeleiteten Klasse immer als erstes aufgerufen wird. class BasisKlasse { protected double feld1; protected BasisKlasse( ) { this.feld1 = 5; } } class AbgeleiteteKlasse : BasisKlasse private int feld2; public AbgeleiteteKlasse(double d, int e) { this.feld2 = e; } . . .
Methoden
Vererbte Methoden Alle (ausser den privaten) Methoden der Basisklasse sind auch in der vererbten Klasse vorhanden (so als wären es die eigenen). class BasisKlasse { protected double BasisMethode(double a) return a*a; } class AbgeleiteteKlasse : BasisKlasse public double Methode(double arg1, double arg2) double resultat = base.BasisMethode(arg1); return resultat * arg2; base zeigt an, dass es eine Methode der Basisklasse ist.
Beispiel: Geometrische Figuren
Basisklasse GeomFigur public class GeomFigur // Basisklasse für geometrische Figuren { protected double[] seiten; protected GeomFigur(double[] s) Console.Write("GeomFigur-Konstuktor"); seiten = s; } public String Information() String result = "Seitenlängen:"; foreach (double d in seiten) { result = result + " " + d; } return result; protected double Summe() double laenge = 0; for(int i=0; i< seiten.Length; i++) { laenge = laenge + seiten[i]; } return laenge;
Von GeomFigur abgeleitete Klasse Rechteck public class Rechteck : GeomFigur { public Rechteck(double[] s) : base(s) Console.Write(" --> Rechteck-Konstruktor"); } public double Umfang() return 2 * base.Summe(); public double Flaeche() return seiten[0] * seiten[1]; Der Konstruktor benutzt den Konstruktor der Basisklasse zum Speichern der Seiten. Die Methode Umfang benutzt die Methode Summe der Basisklasse Die Methode Information wird geerbt und muss nicht mehr implementiert werden.
Abgeleitete Klasse Polygon Von GeomFigur abgeleitete Klasse für Polygone public class Polygon : GeomFigur { public Polygon(double[] s) : base(s) Console.Write(" --> Polygon-Konstruktor"); } public double Umfang() return base.Summe();
Von Polygon abgeleitete Klasse Dreieck Der Konstruktor ruft den Konstruktor der Klasse Rechteck auf Die Methoden Information und Umfang wird geerbt (und muss darum nicht implementiert werden). Die Klasse Dreieck ist von der Klasse Polygon und darum nur indirekt von der Klasse GeomFigur abgeleitet. public class Dreieck : Polygon { public Dreieck(double[] s): base(s) Console.Write(" --> Dreieck-Konstruktor"); }
Benutzen der verschiedenen Klassen static void Main(string[] args) { double[] sValues = new double[] { 3, 4, 2, 1, 5 }; Polygon s = new Polygon(sValues); Console.WriteLine("\nPolygon: {0}", s.Information()); Console.WriteLine("Umfang:{0}", s.Umfang()); double[] tValues = new double[] { 3, 4, 5 }; Dreieck t = new Dreieck(tValues); Console.WriteLine("\nDreieck: {0}", t.Information()); Console.WriteLine("Umfang:{0}", t.Umfang()); double[] rValues = new double[] { 3, 4 }; Rechteck r = new Rechteck(rValues); Console.WriteLine("\nRechteck: {0}", r.Information()); Console.WriteLine("Fläche:{0}", r.Flaeche()); Console.WriteLine("Umfang:{0}", r.Umfang()); } Polygon Dreieck Rechteck
Beispiel: Leih Objekte
Basisklasse LeihObjekt public class LeihObjekt { private int id; private String title; public String Title // Title Eigenschaft (Property) get { return title; } } public static int counter; // statischer Zähler protected LeihObjekt(String t) // Konstruktor id = ++counter; title = t; Console.Write("--> LeihObjekt"); protected String Info() return id + ". " + title; Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Abgeleitete Klasse DVD public class DVD:LeihObjekt { private String regisseur; public DVD(String t, String r):base(t) regisseur = r; Console.Write("--> DVD"); } public String getDVDInfo() return base.Info() + ", Regisseur: " + regisseur; Aufruf des Basis- Konstruktors Aufruf der vererbten Methode Info() Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Abgeleitete Klasse PrintMedium public class PrintMedium : LeihObjekt { private String verlag; public PrintMedium(String t, String v):base(t) verlag = v; Console.Write("--> PrintMedium"); } public String getInfo() return base.Info()+ " des Verlags "+ this.verlag; Aufruf des Basis- Konstruktors Aufruf der vererbten Methode Info() Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Abgeleitete Klasse Buch von PrintMedium public class Buch : PrintMedium { private String autor; public Buch(String t, String p, String a):base(t,p) this.autor = a; Console.Write("--> Buch"); } public String getBuchInfo() return base.getInfo() + ", Autor: " + autor; Aufruf des Konstruktors von PrintMedium Aufruf der vererbten Methode getInfo() von PrintMedium Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Benutzen der verschiedenen Klassen class Program { static void Main(string[] args) PrintMedium z = new PrintMedium("Das neue Heft", "Heft Verlag"); Console.WriteLine(z.getInfo()); Buch b = new Buch("Das neue Buch", "Buch Verlag", "Buch Autor"); Console.WriteLine(b.getBuchInfo()); DVD d1 = new DVD("Der neue Film", "Film Regisseur"); Console.WriteLine(d1.getDVDInfo()); DVD d2 = new DVD("Der zweite neue Film", "Film Regisseur"); Console.WriteLine("Weiterer Film: {0}", d2.Title); Console.WriteLine("Anzahl Leihobjekte: {0}", LeihObjekt.counter); Console.ReadLine(); } Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Program: Ausgabe der Main Methode Die Konstruktoren rufen jeweils den Konstruktor der Basisklasse auf. Zuerst wird immer der Konstruktor der “tiefsten” Stufe, dann aufwärts die Konstruktoren der Ableitungs-Hierarchie aufgerufen. Die „Info-“Methoden benutzen jeweils die „Info“-Methoden der Basis-Klasse. Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012