Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Vererbung.

Ähnliche Präsentationen


Präsentation zum Thema: "Vererbung."—  Präsentation transkript:

1 Vererbung

2 Das Prinzip der Vererbung im täglichen Leben:

3 Walter besitzt ein Haus.

4 Walter erbt nun 10000Euro. Also besitzt er insgesamt:
+ 10000

5 Erben (abgeleitete Klasse) selbst basteln
In Java: Erblasser ---> Erbe In Java darf man einen Erben (abgeleitete Klasse) selbst basteln abgeleitete Klasse Basisklasse --->

6 Statt Basisklasse sagt man auch: Oberklasse, Vaterklasse

7 Statt abgeleiteter Klasse sagt man auch: Unterklasse, Sohnklasse, Subklasse

8 Eine abgeleitete Klasse wird in Java wie folgt angegeben:
class Ei extends Huhn{ ... } Bezeichner Basisklasse abgeleitete Klasse

9 Die abgeleitete Klasse (kurz: Ableitung) besitzt automatisch alle Member (Ausnahme: Konstruktor) der Basisklasse.

10 Beispiel:

11 Von einem Flachdachhaus wird ein Modell (Draufsicht) erstellt:

12 Der Einfachheit halber wird nur die Grundfläche (ohne Zimmer, usw
Der Einfachheit halber wird nur die Grundfläche (ohne Zimmer, usw.) des Hauses abgebildet. Aufgabe: Realisieren Sie die Klasse Modell in Java.

13 class Modell{ private double l; private double b; public Modell(double pl, double pb){ l = pl; b = pb; } public void setL(double pl){ } // weiter...

14 public void setB(double pb){
b = pb; } public double getL(){ return(l); public double getB(){ return(b); public double getFlaeche(){ return(l*b); };

15 Jetzt soll ein “genaueres“ Modell des Flachdachhauses erstellt werden: Modell aus Styropor (oder Ton). Aufgabe: Realisieren Sie in Java die Klasse Gmodell.

16 Standardmäßig könnte man das mit den 3 Attributen Länge, Breite, Höhe und den zugehörigen set- und get-Methoden machen. Also wie folgt:

17 class Gmodell{ private double l; private double b; private double h; public Gmodell(double pl, double pb, double ph){ l = pl; b = pb; h = ph; }

18 public void setL(double pl){
l = pl; } public void setB(double pb){ b = pb; public double getL(){ return(l); public double getB(){ return(b);

19 public void setH(double ph){
h = ph; } public double getH(){ return(h); public double getVolumen(){ return(l*b*h); };

20 Gibt es eine andere Lösung, bei der man sich Schreibarbeit sparen kann
Gibt es eine andere Lösung, bei der man sich Schreibarbeit sparen kann? Wie kann man Softwareteile dabei wiederverwenden ? Indem man die Vererbung benutzt.

21 Welche Member der Klasse Modell kann man übernehmen (erben)
Welche Member der Klasse Modell kann man übernehmen (erben) ? Welche Member kommen neu dazu ?

22 Welche Member müssen neu dazu ?
class Modell{ private double l; private double b; public Modell(double pl, double pb){... public void setL(double pl){... public void setB(double pb){... public double getL(){... public double getB(){... public double getFlaeche(){... }; Alle außer dem Konstruktor Welche Member müssen neu dazu ? Welche Member werden vererbt ?

23 public void setL(double pl){... public void setB(double pb){...
extends Modell{ class Gmodell private double l; private double b; public: public void setL(double pl){... public void setB(double pb){... public double getL(){... public double getB(){... public double getFlaeche(){... } Die reliefförmig dargestellten Member werden geerbt. private double h; Wie wird eine Vererbung erreicht ? Die rot dargestellten Member kommen neu dazu. public Gmodell(double pl, double pb,double ph){... public void setH(double ph){... public double getH(){... public double getVolumen(){...

24 Aufgabe: Schreiben Sie das komplette Programm mit den zugehörigen Klassen in Java

25 public class MainVererbung1{
public static void main(String[] args){ // Anweisungen siehe später } class Modell{ private double l; private double b; public Modell(double pl, double pb){ l = pl; b = pb;

26 public void setL(double pl){
l = pl; } public void setB(double pb){ b = pb; public double getL(){ return(l); public double getB(){ return(b); public double getFlaeche(){ return(l*b); };

27 class Gmodell extends Modell{ private double h;
public Gmodell(double pl, double pb, double ph){ super(pl,pb); setH(ph); } public void setH(double ph){ h = ph; public double getH(){ return(h); public double getVolumen(){ return(getFlaeche()*h); Diese Methode gibt es nicht in der Klasse Gmodell. Warum kann sie trotzdem verwendet werden? Weil ... 1) Die Methode von der Klasse Modell vererbt wird und es sie deshalb in Gmodell gibt 2) Weil die Methode public ist, kann auf sie zugegriffen werden. Mit super wird ein Konstruktor der Oberklasse aufgerufen. Näheres dazu später.

28 class Gmodell extends Modell{ private double h;
public Gmodell(double pl, double pb, double ph){ super(pl,pb); setH(ph); } public void setH(double ph){ h = ph; public double getH(){ return(h); public double getVolumen(){ return(getFlaeche()*h); Wie heißt der Konstruktor der Oberklasse und wie viele Parameter hat er? Der Konstruktor heißt Modell und er hat zwei Parameter

29 class Gmodell extends Modell{ private double h;
public Gmodell(double pl, double pb, double ph){ super(pl,pb); setH(ph); } public void setH(double ph){ h = ph; public double getH(){ return(h); public double getVolumen(){ return(getFlaeche()*h); Was könnte man statt dem Aufruf der Methode setH(ph) auch noch machen? h = ph;

30 Warum ist folgende Lösung falsch?

31 class Gmodell extends Modell{ private double h;
public Gmodell(double pl, double pb, double ph){ super(pl,pb); setH(ph); } public void setH(double ph){ h = ph; public double getH(){ return(h); double getVolumen(){ return(b*l*h); Warum ist diese Lösung falsch ? Die Member b und l gibt es zwar in der Klasse GModell (sie wurden vererbt). Allerdings sind sie private. Auf vererbte private-Member kann weder innerhalb noch außerhalb der Klasse zugegriffen werden.

32 class Gmodell extends Modell{ private double h;
public Gmodell(double pl, double pb, double ph){ super(pl,pb); setH(ph); } public void setH(double ph){ h = ph; public double getH(){ return(h); double getVolumen(){ return(b*l*h); Die Methoden getB() und getL() sind public. Deswegen dürfen sie benutzt werden. Welche Lösung wäre auch noch möglich? return(getB()*getL()*h);

33 class Gmodell extends Modell{ private double h;
public Gmodell(double pl, double pb, double ph){ super(pl,pb); setH(ph); } public void setH(double ph){ h = ph; public double getH(){ return(h); double getVolumen(){ return(b*l*h); h wird nicht vererbt und ist ein Attribut von Gmodell. Deshalb kann man innerhalb der Klasse Gmodell auf h zugreifen. Warum muss man getB() und getL() verwenden, aber nicht getH(), sondern h ? return(getB()*getL()*h);

34 class Gmodell extends Modell{ private double h;
public Gmodell(double pl, double pb, double ph){ super(pl,pb); setH(ph); } public void setH(double ph){ h = ph; public double getH(){ return(h); double getVolumen(){ return(pb*pl*h); Warum ist das nicht korrekt? Auf die Variablen pb und pl kann nicht zugegriffen werden, da sie weder ... ein Attribut der Klasse, noch ein Parameter bzw. eine lokale Variable der Methode getVolumen() sind.

35 public Gmodell(double pl, double pb, double ph){ super(pl,pb);
setH(ph); } Da die Klasse Gmodell von der Klasse Modell erbt, muss beim Anlegen eines Objekts der Klasse Gmodell auch der Konstruktor der Klasse Modell aufgerufen werden. Wird dies nicht gemacht, dann wird automatisch (ohne Zutun des Programmierers) der Standardkonstruktor der Klasse Modell aufgerufen. Was passiert, wenn der Standardkonstruktor nicht existiert ? Dann wird dieser automatisch vom Compiler angelegt, außer .... es gibt einen Konstruktor mit (1, 2, 3, ...) Parametern. Dann liefert der Compiler eine Fehlermeldung.

36 Merke Wenn ein Konstruktor der Unterklasse nicht mittels super(
Merke Wenn ein Konstruktor der Unterklasse nicht mittels super(...) einen Konstruktor der Oberklasse aufruft, dann wird automatisch der Standardkonstruktor (=Konstruktor mit 0 Parametern) der Oberklasse aufgerufen. Der Sinn davon ist, dass alle Attribute (auch die der Oberklassen) einen definierten Wert bekommen sollen, auch wenn der Programmierer vergisst, den Konstruktor der Oberklasse aufzurufen.

37 Falls dieser Standardkonstruktor nicht existiert, wird er automatisch vom Compiler erzeugt, außer ein anderer Konstruktor (mit mindestens einem Parameter) existiert schon. In diesem Fall bringt der Compiler dann eine Fehlermeldung. Wenn man super(...) in einem Konstruktor benutzt, muss dies die erste Anweisung in dem Konstruktor sein, d.h. vor super(...) darf keine Anweisung stehen!

38 public Gmodell(double pl, double pb, double ph){ super(pl,pb);
setH(ph); } Was würde also geschehen, wenn man diese Anweisung in unserem Programm weglassen würde? Dann würde automatisch der Standardkonstruktor der Klasse Modell aufgerufen werden. Da dieser nicht existiert und er auch nicht automatisch erzeugt wird (da es ja schon in der Klasse Modell einen Konstruktor mit zwei Parametern gibt) meldet der Kompiler einen Fehler.

39 Beispiel für die Benutzung der o. g. Klassen in einem Hauptprogramm
Beispiel für die Benutzung der o.g. Klassen in einem Hauptprogramm. Welche Werte bekommen die Variablen in den Zuweisungen?

40 public class MainVererbung1{ public static void main(String[] args){
Modell m = new Modell(10,20); Gmodell g = new Gmodell(2,3,4); double a,b,c,f,v; // ... } Bevor wir näher auf die einzelnen Anweisungen eingehen, noch eine Frage: Was ist streng genommen falsch bei dem Aufruf mit den obigen Parametern Die Parameter müssen eigentlich alle vom Datentyp double sein und nicht von Datentyp int. Doch der Compiler ist hier gutmütig, verzeiht und wandelt int in double um. Stichwort: "Parameterübergabe und Konvertierung" am Schluss dieser Präsentation.

41 public class MainVererbung1{ public static void main(String[] args){
Modell m = new Modell(10,20); Gmodell g = new Gmodell(2,3,4); double a,b,c,f,v; // ... } Adresse Wert ... 0420 l=10 b=20 Was ist m ? Was geschieht im Arbeitsspeicher? m Im Arbeitsspeicher wird "irgendwo" Speicher für ein Objekt reserviert, auf das m zeigt. Dieses Objekt besteht aus 2 "Schubladen" l und b und wird durch den zweiparametrigen Konstruktor Modell vorbelegt

42 public class MainVererbung1{ public static void main(String[] args){
Modell m = new Modell(10,20); Gmodell g = new Gmodell(2,3,4); double a,b,c,f,v; // ... } Adresse Wert ... 0420 l=10 b=20 Was ist g ? Was geschieht im Arbeitsspeicher? m Im Arbeitsspeicher wird "irgendwo" Speicher für ein Objekt reserviert, auf das g zeigt. Dieses Objekt besteht aus 3 "Schubladen" l, b h und wird durch den dreiparametrigen Konstruktor Gmodell vorbelegt. 0470 l=2 b=3 h=4 g

43 public class MainVererbung1{ public static void main(String[] args){
Modell m = new Modell(10,20); Gmodell g = new Gmodell(2,3,4); double a,b,c,f,v; // ... } Adresse Wert ... 0420 l=10 b=20 Gibt es einen Zusammenhang zwischen m und g ? m nein! 0470 l=2 b=3 h=4 g

44 public class MainVererbung1{ public static void main(String[] args){
Die Methode gibt es nicht in der Klasse Modell public class MainVererbung1{ public static void main(String[] args){ Modell m = new Modell(10,20); Gmodell g = new Gmodell(2,3,4); double a,b,c,f,v; a = m.getL(); b = m.getB(); c = m.getH(); f = m.getFlaeche(); v = m.getVolumen(); a = g.getL(); b = g.getB(); c = g.getH(); f = g.getFlaeche(); v = g.getVolumen(); } Die Methode gibt es nicht in der Klasse Modell Was bewirken die folgenden Anweisungen? // a=10 // b=20 // Fehler !! // f=200 // Fehler !! // a=2 // b=3 // c=4 // f=6 // v=24

45 Verdeckte Member

46 class Gmodell extends Modell{ private double h;
public Gmodell(double pl, double pb, double ph){... public void setH(double ph){... public double getH(){... public double getVolumen(){... public double getFlaeche(){... } Alles gleich wie vorher außer, daß eine Methode gleichen Namens wie in der Basisklasse existiert, die die Oberfläche des Modells (Quaders) berechnet. Wie muss sie implementiert werden ?

47 public double getFlaeche(){ return(2*(getL()*getB()+getL()*h
+getB()*h)); } Warum ist diese Lösung falsch ? Die Member b und l gibt es zwar in der Klasse GModell (sie wurden vererbt). Allerdings sind sie private. Auf vererbte private-Member kann weder innerhalb noch außerhalb der Klasse zugegriffen werden. public double getFlaeche(){ return(2*(l*b+l*h+b*h)); }

48 public class MainVererbung1{ public static void main(String[] args){
Es wird auf die Methode der Unterklasse und nicht der Oberklasse zugegriffen, weil die Methode der Oberklasse durch die Methode der Unterklasse verdeckt wird. public class MainVererbung1{ public static void main(String[] args){ double f; Gmodell g = new Gmodell(2,3,4); f = g.getFlaeche(); } // f=52 // 52=2(2*3+2*4+3*4) Von welcher Klasse (Modell oder Gmodell) wird diese Methode aufgerufen ?

49 public class MainVererbung1{ public static void main(String[] args){
Merke: Wenn die Methode in mehreren Klassen einer Vererbungshierarchie vorkommt, wird - relativ zu dem aktuellen Objekt aus gesehen - auf die in der Vererbungshierarchie am weitesten unten stehende Methode zugegriffen. Also: public class MainVererbung1{ public static void main(String[] args){ double f; Gmodell g = new Gmodell(2,3,4); f = g.getFlaeche(); } Wenn die Methode in der Unterklasse und in der Oberklasse vorkommt und auf ein Objekt der Unterklasse zugegriffen wird, wird auf die Methode der ... Unterklasse zugegriffen Wenn die Methode in der Unterklasse, aber nicht in der Oberklasse vorkommt und auf ein Objekt der Unterklasse zugegriffen wird, wird auf die Methode der ... // f=52 Unterklasse zugegriffen // 52=2(2*3+2*4+3*4) Wenn die Methode nicht in der Unterklasse, aber in der Oberklasse vorkommt und auf ein Objekt der Unterklasse zugegriffen wird, wird auf die Methode der ... Oberklasse zugegriffen

50 public double getFlaeche(){ return(2*(h*getB()+h*getL()+
getL()*getB())); } getFlaeche könnte man auch anders implementieren ... public double getFlaeche(){ double temp; temp= h*getL() + h*getB(); temp=2*(super.getFlaeche()+temp); return(temp); } Mit super ruft man die verdeckte Methode der Oberklasse auf, wobei super nicht die erste Anweisung in der Methode sein muss.

51 Der Zugriffschutz protected

52 Zuerst ein kleiner Ausflug

53 Ein package (deutsch Paket) ist ein besonderes Verzeichnis (auf der Festplatte), in dem sich eine Menge von "zusammengehörigen" Klassen (ähnlich einer Programmbibliothek) befindet. Diese Klassen sind in einer (wir haben bis jetzt immer nur eine java-Datei verwendet) oder mehreren Java-Dateien (mit der Endung "java") gespeichert. Unterhalb dieses Verzeichnisses müssen sich diese o.g. Java-Dateien befinden. Ein package wird dadurch gekennzeichnet, dass in der 1. Zeile der Bezeichner package steht, wie z.B: package myPaket;

54 Wenn der Bezeichner package nicht angegeben wird, wird automatisch (ohne Zutun des Programmierers) ein spezielles package angelegt: Das Default package Das Default package ist das aktuelle Verzeichnis. Professionelle Entwickler verwenden kein Default package (es wird davon abgeraten), weil z.B. Klassen aus anderen Packages als dem Default Package nicht auf das Default Package zugreifen können.

55 ja nein Spezifizierer in gleicher Klasse in Unterklasse mit Vererbung
in gleichem Package überall private ja nein protected public nichts angegeben Wir schauen uns folgendes Beispiel mit protected (im Vergleich zu public) an: Member ist nicht in der gleichen Klasse, nicht in einer Unterklasse davon und nicht im gleichen package ja: Zugriff möglich nein: Zugriff nicht möglich

56 Inhalt der Datei hund.java:
package mypackHund; public class Hund{ public String name; protected double gewicht; public Hund(String pName, double pGewicht){ this.name = pName; } // und weitere get- und set-Methoden

57 Inhalt der Datei katze.java:
package mypackKatze; public class Katze{ // das Übliche }

58 Inhalt der Datei Unterschied.java:
Warum funktioniert dieser Zugriff nicht? package unterschiedPack; import mypackHund.Hund; // import mypackHund.*; public class Startklasse{ public static void main() { Hund h = new Hund("Bello", 10); h.name="Hasso"; h.gewicht=12; } Warum kann auf die Klasse Hund zugegriffen werden, obwohl sie hier nicht implementiert wurde? Weil sie hier importiert wurde. Weil auf ein public-Member von überall aus zugegriffen werden kann. Warum funktioniert dieser Zugriff?

59 Inhalt der Datei Unterschied.java:
Weil auf das protected-Member gewicht der Klasse Hund nicht von überall aus zugegriffen werden kann, sondern nur von der gleichen Klasse Hund, einer Unterklasse von Hund oder von Klassen aus ... package unterschiedPack; import mypackHund.Hund; // import mypackHund.*; public class Startklasse{ public static void main() { Hund h = new Hund("Bello", 10); h.name="Hasso"; h.gewicht=12; } die sich im gleichen package wie die Klasse Hund befinden. Die Klassen "Startklasse" und "Hund" befinden sich aber nicht im gleichen package.

60 Inhalt der Datei Unterschied.java:
Eine Bemerkung zum Schluss... importiert die Datei Hund.java des Verzeichnisses hundePack package unterschiedPack; import mypackHund.Hund; // import mypackHund.*; public class Startklasse{ public static void main() { Hund h = new Hund("Bello", 10); h.name="Hasso"; h.gewicht=12; } anstatt einer Datei kann auch ein Platzhalter verwendet werden. Es werden dann alle Java-Dateien des Verzeichnisses hundePack nach den benötigten Klassen durchsucht.

61 Ende des Ausflugs. Weitere, ausführlichere Infos zu packages,
siehe Java-Skript auf meiner Website:

62 class Gmodell extends Modell{ private double h;
public Gmodell(double pl, double pb, double ph){ super(pl,pb); setH(ph); } public void setH(double ph){ h = ph; public double getH(){ return(h); public double getVolumen(){ return(b*l*h); Wiederholung: Warum ist diese Lösung falsch ? Die Member b und l gibt es zwar in der Klasse Gmodell (sie wurden vererbt). Allerdings sind sie private. Auf vererbte private-Member kann weder innerhalb noch außerhalb der Unterklasse zugegriffen werden.

63 class Gmodell extends Modell{ private double h;
public Gmodell(double pl, double pb, double ph){ super(pl,pb); setH(ph); } public void setH(double ph){ h = ph; public double getH(){ return(h); public double getVolumen(){ return(b*l*h); Was muss man machen, damit diese Lösung funktioniert? Eine Möglichkeit wäre, b und l der Oberklasse public zu machen. Dann könnte man auch von innerhalb einer Methode der Unterklasse auf diese vererbten Member zugreifen. Welchen Nachteil hätte dies aber? Man könnte auch von außerhalb einer Methode auf die Attribute b und l zugreifen. Das widerspricht der Philosophie der objektorientierten Programmierung.

64 class Gmodell extends Modell{ private double h;
public Gmodell(double pl, double pb, double ph){ super(pl,pb); setH(ph); } public void setH(double ph){ h = ph; public double getH(){ return(h); public double getVolumen(){ return(b*l*h); In der Oberklasse kann man den Zugriffsschutz von b und l (der bisher private war) auf protected setzen. Damit kann man auch von innerhalb einer Methode der Unterklasse auf diese vererbten Member zugreifen. Von außerhalb einer Methode kann man (bei protected) nicht mehr auf die Attribute b und l zugreifen, außer... die Klasse (hier: MainVererbung1) von der aus auf das protected - Attribut einer anderen Klasse (hier: Modell oder Gmodell) zugegriffen wird, befinden sich im gleichen Package (Default package). Da das bisher bei uns der Fall war, unterscheiden sich public und protected nicht.

65 public class MainVererbung1{ public static void main(String[] args){
Modell m = new Modell(10,20); Gmodell g = new Gmodell(2,3,4); double x1, x2; x1 = m.l; m.b = 5; x2 = g.l; g.b = 13; } class Modell{ protected double l; protected double b; // Rest wie früher // class Gmodell wie früher Wann funktionieren diese Zugriffe von außerhalb nur? MainVererbung1, Modell oder Gmodell sind im gleichen Package.

66 Darstellung der Vererbung durch UML

67 Basisklasse Subklasse
... Attribute Methoden Attribute Methoden Pfeil bedeutet: erbt von Subklasse ... Analog zum Zugriffsschutz + (public) und – (private) bedeutet # : protected

68 Aufgabe: Stellen Sie die Klassen Modell, Gmodell und ihre Vererbungshierarchie in UML dar.

69 Modell - l: double - b: double + Modell(pl:double, pb:double) + setL(pl:double): void + setB(pb:double): void + getL():double + getB():double + getFlaeche():double Statt dem Zugriffschutz + oder - kann auch der Zugriffschutz # benutzt werden, also ... Gmodell - h: double + Gmodell(pl:double, pb:double, ph:double) + setH(ph:double): void + getH():double + getVolumen():double

70 Modell # l: double # b: double + Modell(pl:double, pb:double) + setL(pl:double): void + setB(pb:double): void + getL():double + getB():double + getFlaeche():double Gmodell - h: double + Gmodell(pl:double, pb:double, ph:double) + setH(ph:double): void + getH():double + getVolumen():double

71 Wann soll man eine Vererbung sinnvoll einsetzen ?

72 wenn die folgende Beziehung besteht: Subklasse "ist ein(e)" Basisklasse. Im Gegensatz zu einer Aggregation. Dort besteht die Beziehung "hat" bzw. "besteht aus"

73 Beispiele der Vererbung: Ein LKW ist ein Fahrzeug Eine Katze ist ein Tier Eine Tulpe ist eine Pflanze abgeleitete Klasse Basisklasse

74 Der Prozeß, um von einer Basisklasse durch Detaillierung und Konkretiserung zu einer Subklasse zu kommen, nennt man Spezialisierung. Der Prozeß, um von einer Subklasse durch Verallgemeinerung und Abstraktion zur Basisklasse zu kommen, nennt man Generalisierung.

75 Bemerkung: Die Klasse Object ist die oberste aller Klassen (Mutter aller Klassen). Jede Klasse ist automatisch Unterklasse dieser Klasse, ohne daß dies durch extends extra angegeben werden muß.

76 Parameterübergabe und Konvertierung

77 I) Wenn eine Methode verlangt, dass ein Parameter einen primitiven Datentypen wie z.B. double haben muss, aber beim Methodenaufruf ein integer Wert benutzt wird, dann wird der "kleinere" Datentyp (hier also int) automatisch in den "größeren" Datentyp konvertiert (impliziter cast).

78 Beispiel (siehe Klasse Hund): Es soll der Hund Goldi mit 10
Beispiel (siehe Klasse Hund): Es soll der Hund Goldi mit 10.5 Kg Gewicht erzeugt werden. Anschließend soll dieses Gewicht auf 15 Kg abgeändert werden (Hund hat zugenommen).

79 class Hund{ // wie vorher }
public class MainKlassen1 { public static void main(String[] args){ Hund myh1; myh1=new Hund(); myh1.setName("Goldi"); myh1.setGewicht(10.5); myh1.setGewicht(15); } } class Hund{ // wie vorher } 10.5 ist ein Literal und hat den Datentyp double. Laut der Deklaration der Methode setGewicht(...) muß er auch diesen Datentyp haben. Welchen Datentyp hat dieser aufrufende (aktuelle) Parameter und welchen Datentyp müsste er laut Deklaration der Methode setGewicht(...) haben?

80 class Hund{ // wie vorher }
public class MainKlassen1 { public static void main(String[] args){ Hund myh1; myh1=new Hund(); myh1.setName("Goldi"); myh1.setGewicht(10.5); myh1.setGewicht(15); } } class Hund{ // wie vorher } Der Compiler müsste also streng genommen eine Fehlermeldung bringen .... Er macht dies allerdings nicht, sondern wandelt automatisch den „kleineren“ Datentyp integer (also konkret 15) in den „größeren“ Datentyp double (also konkret 15.0) um! 15 ist ein Literal und hat den Datentyp integer. Laut der Deklaration der Methode setGewicht(...) müsste er aber den Datentyp double haben. Welchen Datentyp hat dieser aufrufende (aktuelle) Parameter und welchen Datentyp müsste er laut Deklaration der Methode setGewicht (...) haben?

81 II) a) Wenn eine Methode verlangt, dass ein Parameter als Datentyp eine Klasse haben muss, aber beim Methodenaufruf ein Objekt einer Unterklasse davon übergeben wird, dann wird das Objekt vor der Übergabe an den Parameter automatisch in das Objekt der Oberklasse konvertiert (impliziter cast).

82 b) Umgekehrt geht es nicht: Ein Objekt einer Oberklasse kann nicht an einen Parameter einer Methode übergeben werden, die ein Objekt einer Unterklasse erwartet.

83 Beispiel (Klasse Modell und GModell wie im früheren Beispiel)

84 package parameteruebergabe1; public class MainParameter1 {
public static void main(String[] args){ Modell m = new Modell(10,20); Gmodell g = new Gmodell(2,3,4); changeLaenge(m, 20); changeLaenge(g, 40); System.out.println(m.getL()); System.out.println(g.getL()); } public static void changeLaenge( Modell pModell, double pl){ double tempLaenge; tempLaenge = pModell.getL(); pModell.setL(tempLaenge+pl); Die Methode changeLaenge verlangt den Datentyp Modell welchen Datentyp (Klasse) muß diese Variable haben und warum? Warum ist dann dieser Aufruf richtig? Warum muß hier static stehen? Dies wird später behandelt! Weil g automatisch in das Objekt von Datentyp Modell konvertiert wird.


Herunterladen ppt "Vererbung."

Ähnliche Präsentationen


Google-Anzeigen