Benutzer-Werkzeuge

Webseiten-Werkzeuge


klassen2:polymorphismus:start

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
klassen2:polymorphismus:start [2020/04/30 12:08] Martin Pabstklassen2:polymorphismus:start [2021/12/29 11:29] (aktuell) – Externe Bearbeitung 127.0.0.1
Zeile 1: Zeile 1:
 ====== Überschreiben von Methoden, Polymorphismus ====== ====== Überschreiben von Methoden, Polymorphismus ======
 Im folgenden Beispiel sind die Klassen ''Rechteck'' und ''Kreis'' Unterklassen der Klasse ''Figur''. Letztere besitzt ein Attribut ''Farbe'' und eine Methode ''schreibeDaten()'' mit der grundlegenden Funktionalität, diese Farbe auszugeben. Es ist nicht sinnvoll, Objekte der Klasse ''Figur'' zu instanzieren, daher haben wir die Klasse als ''abstract'' deklariert. Im folgenden Beispiel sind die Klassen ''Rechteck'' und ''Kreis'' Unterklassen der Klasse ''Figur''. Letztere besitzt ein Attribut ''Farbe'' und eine Methode ''schreibeDaten()'' mit der grundlegenden Funktionalität, diese Farbe auszugeben. Es ist nicht sinnvoll, Objekte der Klasse ''Figur'' zu instanzieren, daher haben wir die Klasse als ''abstract'' deklariert.
-<code java>+<code learnj>
 abstract class Figur { abstract class Figur {
        
Zeile 18: Zeile 18:
 </code> </code>
 Die Klasse ''Rechteck'' ist eine Unterklasse der Klasse ''Figur'' und besitzt über das Attribut ''Farbe'' hinaus noch die Attribute ''Breite'' und ''Länge''. Die Methode ''schreibeDaten()'' der Klasse Figur ist für Rechteck-Objekte nicht mehr hinreichend, da bei diesen Objekten auch die Länge und die Breite ausgegeben werden soll.  Die Klasse ''Rechteck'' ist eine Unterklasse der Klasse ''Figur'' und besitzt über das Attribut ''Farbe'' hinaus noch die Attribute ''Breite'' und ''Länge''. Die Methode ''schreibeDaten()'' der Klasse Figur ist für Rechteck-Objekte nicht mehr hinreichend, da bei diesen Objekten auch die Länge und die Breite ausgegeben werden soll. 
-=== Überschreiben von Methoden === +==== Überschreiben von Methoden ==== 
-Wir schreiben in die Klasse ''Rechteck'' daher eine weitere Methode ''schreibeDaten()'' mit derselben Signatur (d.h. demselben Bezeichner, denselben Parametertypen und demselben Rückgabedatentyp) wie die Methode der Oberklasse Figur. Man sagt: **"Wir überschreiben die Methode ''schreibeDaten()'' der Klasse ''Figur'' in der Klasse ''Rechteck''."** +Wir schreiben in die Klasse ''Rechteck'' daher eine weitere Methode ''schreibeDaten()'' mit derselben Signatur (d.h. demselben Bezeichner, denselben Parametertypen und demselben Rückgabedatentyp) wie die Methode der Oberklasse Figur. Man sagt: **"Wir überschreiben die Methode ''schreibeDaten()'' der Klasse ''Figur'' in der Klasse ''Rechteck''."** \\  
-<code java>+Natürlich soll auch bei Rechtecken neben der Länge und der Breite noch deren Farbe ausgegeben werden. Wir wollen daher in der Methode ''schreibeDaten()'' der Klasse ''Rechteck'' die gleichnamige Methode der Oberklasse ''Figur'' aufrufen. Dazu benutzen wir - wie auch schon bei Konstruktoren - das Schlüsselwort ''super''. \\  
 +<WRAP center round info 60%> 
 +**Wir erinnern uns:** \\  
 +Innerhalb des Konstruktors einer Unterklasse ist der Aufruf des Konstruktors der Oberklasse mittels ''super'' **verpflichtend**. Diese Pflicht besteht bei anderen überschriebenen Methoden nicht. 
 +</WRAP> 
 + 
 +<code learnj [enable_line_numbers="true",highlight_lines_extra="13"]>
 class Rechteck extends Figur { class Rechteck extends Figur {
        
Zeile 33: Zeile 39:
  
    public void schreibeDaten() {    public void schreibeDaten() {
-      super.schreibeDaten();+      super.schreibeDaten();              // Aufruf der gleichnamigen Methode der Oberklasse
       println("Breite: " + breite, Color.lightblue);       println("Breite: " + breite, Color.lightblue);
       println("Höhe: " + höhe, Color.lightblue);       println("Höhe: " + höhe, Color.lightblue);
Zeile 39: Zeile 45:
 } }
 </code> </code>
 +
 +Wird nun bei einem ''Rechteck''-Objekt die Methode ''schreibeDaten()'' aufgerufen, so kommt immer die Methode der Klasse ''Rechteck'' zum Zug, nicht die Methode der Oberklasse ''Figur''. Probiere es im folgenden Beispiel aus, indem Du das Programm im Einzelschrittmodus "step into ({{:klassen2:constructors:step-into-dark.png?nolink|}})" ausführst!
 +
  
 <HTML> <HTML>
  
-<div class="java-online" style="height: 400px; width: 100%" data-java-online="{}">+<div class="java-online" style="height: 400px; width: 100%" data-java-online="{'id': 'Polymorphismus1', 'withBottomPanel': true}">
  
 <script type="text/plain" title="Main.java"> <script type="text/plain" title="Main.java">
-Figur = new Rechteck("rot", 10, 20); +Figur f1 = new Rechteck("rot", 10, 20); 
-Figur = new Kreis("grün", 30);+Figur f2 = new Kreis("grün", 30);
  
-r.schreibeDaten();+f1.schreibeDaten();
 println(); println();
-k.schreibeDaten();+f2.schreibeDaten();
  
 </script> </script>
Zeile 104: Zeile 113:
 } }
 </script> </script>
 +</div>
  
 +</HTML>
 +
 +==== Polymorphismus ====
 +<WRAP center round info 60%>
 +Beachte die Methodenaufruf in den Zeilen 4 und 6 des Hauptprogramms oben:
 +<code learnj [enable_line_numbers="true", highlight_lines_extra="1,3", start_line_numbers_at="4"]>
 +f1.schreibeDaten();
 +println();
 +f2.schreibeDaten();
 +</code>
 +Die Variablen ''f1'' und ''f2'' sind beide vom selben Datentyp ''Figur''. Trotzdem bewirkt der Aufruf der Methode ''schreibeDaten()'' jeweils etwas anderes. In Zeile 4 wird die Methode ''schreibeDaten()'' der Klasse ''Rechteck'' aufgerufen, in Zeile 6 die Methode ''schreibeDaten()'' der Klasse ''Kreis''. \\ 
 +Diesen Sachverhalt nennt man **Polymorphismus** ("Vielgestaltigkeit", siehe [[https://de.wikipedia.org/wiki/Polymorphie_(Programmierung)|Wikipedia]]), da der Aufruf mit demselben Methodenbezeichner die Ausführung verschiedener Methoden zur Folge hat.
 +</WRAP>
 +Noch eindrucksvoller wirkt der Polymorphismus im folgenden Beispiel:
 +
 +<HTML>
 +
 +<div class="java-online" style="height: 400px; width: 100%" data-java-online="{'id': 'Polymorphismus2', 'withBottomPanel': true}">
 +
 +<script type="text/plain" title="Main.java">
 +Figur[] f = new Figur[2];
 +f[0] = new Rechteck("rot", 10, 20);
 +f[1] = new Kreis("grün", 30);
 +
 +for(int i = 0; i < 2; i++){
 +   f[i].schreibeDaten();
 +   println();
 +}
 +</script>
 +
 +<script type="text/plain" title="Figur.java">
 +abstract class Figur {
 +   
 +   String farbe;
 +
 +   public Figur(String farbe) {
 +      this.farbe = farbe;
 +   }
 +
 +   public void schreibeDaten() {
 +      println("Farbe: " + farbe); 
 +   }
 +
 +}
 +</script>
 +<script type="text/plain" title="Rechteck.java">
 +class Rechteck extends Figur {
 +   
 +   double breite;
 +   double höhe;
 +   
 +   public Rechteck(String farbe, double breite, double höhe) {
 +      super(farbe);
 +      this.breite = breite;
 +      this.höhe = höhe; 
 +   }
 +
 +   public void schreibeDaten() {
 +      super.schreibeDaten();
 +      println("Breite: " + breite, Color.lightblue);
 +      println("Höhe: " + höhe, Color.lightblue);
 +   }
 +}
 +</script>
 +<script type="text/plain" title="Kreis.java">
 +class Kreis extends Figur {
 +   double radius;
 +
 +   public Kreis(String farbe, double radius) {
 +      super(farbe);
 +      this.radius = radius;
 +   }
 +
 +   public void schreibeDaten() {
 +      super.schreibeDaten();
 +      println("Radius: " + radius, Color.yellow);
 +   }
 +
 +}
 +</script>
 </div> </div>
  
 </HTML> </HTML>
 +In Zeile 6 wird beim ersten Schleifendurchlauf die Methode ''schreibeDaten()'' der Klasse ''Rechteck'' aufgerufen, beim zweiten Durchlauf die Methode ''schreibeDaten()'' der Klasse ''Kreis''.
 +<WRAP center round info 60%>
 +Am Beispiel oben wird deutlich, dass der Computer **erst zur Laufzeit** bestimmt, welche der beiden Methoden aufgerufen wird. Man spricht von **[[https://de.wikipedia.org/wiki/Dynamische_Bindung|dynamic Binding]]**.
 +</WRAP>
 +
klassen2/polymorphismus/start.1588241305.txt.gz · Zuletzt geändert: 2021/12/29 11:29 (Externe Bearbeitung)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki