Vorlesung Informatik 1 - Teil A: Java Kurs

2.10 Zuweisungskompatibilität, Polymorphie

Obwohl wir von abstrakten Klassen oder mehr noch von einem Interface keine Objekte erzeugen können, kann man Variablen davon definieren.

Wir verwenden das z.B. in unserer Klasse SpielfFgur:

   public class SpielFigur extends Rectangle2D.Double implements MouseListener, MouseMotionListener {
                 ...
   protected Spiel spiel;

           public SpielFigur(double xC, double yC, double breite, double hoehe, Spiel spiel) {
       super(xC-breite/2, yC-hoehe/2, breite, hoehe);
   this.spiel = spiel;

Die Klasse Spiel ist abstrakt, kann also nicht instanziiert werden - man kann keine Objekte vom Typ Spiel erzeugen.  Trotzdem gibt es eine Instanz- und eine lokale Variable, die offensichtlich auf Objekte dieses Typs zeigen??

Dieser scheinbare Widerspruch löst sich wie folgt auf: 

Variablen vom Typ einer Basisklasse oder vom Typ eines Interface können auf Objekte abgeleiteter bzw. implementierender Klassen zeigen. 
Man sagt Basisklasse und Interface sind zuweisungskompatibel zu abgeleiteten und implementierenden Klassen.

Dieses Prinzip gehört zu den mächtigsten Konzepten  der objektorientierten Programmierung.

Beispiel:

   abstract class Musikinstrument{
           public abstract void spielt();
   }

   class Geige extends Musikinstrument{
       private Klang klang = new Klang("/sound/geige.mp3");
     
@ Override
       public void spielt(){
           klang.play();
       } 
   }

class Bratsche extends Musikinstrument{                           class Cello extends Musikinstrument{                                     
       ...                                                                                                    ...
      @ Override                                                                               @ Override
      public void spielt(){                                                                            public void spielt(){

           ...                                                                                                ...
}  }                                                                                       }  }

Wenn wir jetzt ein Streichquartett programmieren, können wir verschiedene Instrumente in Variablen vom Typ Musikinstrument speichern:

class StreichQuartett{
   Musikinstrument m1, m2, m3, m4;
   public StreichQuartett(Musikinstrument m1, Musikinstrument m2, Musikinstrument m3, Musikinstrument m4){
      this.m1 = m1;
      this.m2 = m2;
      this.m3 = m3;
      this.m4 = m4;
   } 
   public void zusammenSpielen(){
           m1.spiel();
           m2.spiel();
           m3.spielt();
          m4.spielt();
   }
}

Diese Klasse muss gar nicht wissen, um welche Instrumente es sich handelt, sie weiß nur, dass ein Musikinstrument eine Methode spielt() hat. Es können zwei Geigen ein Cello und eine Bratsche sein oder eine andere Zusammensetzung: die Klasse StreichQuartett muss nicht umgeschrieben oder neu kompiliert werden. Musikinstrument kann viele Gestalten annehmen - deshalb Polymorphie.

Noch wichtiger: StreichQuartett funktioniert auch mit zukünftigen Klassen, die von Musikinstrument abgeleitet sind. Wenn wir also zusätzlich die Klasse  ViolinCello  schreiben, änder sich nicht am Streichquartett.

Auch im Zusammenhang mit einem  Interface gilt diese Regel: Klassen, die ein Interface verwenden müssen nicht neu kompiliert werden, wenn es neue Klassen gibt, welche das Interface implementieren.

Man kann mit einer Referenz vom Typ einer Basisklasse oder eines Interface nur auf Methoden der Basisklasse bzw. des Interface zugreifen.

Beispiel:

   class Orgel extends Musikinstrument{
      @ Override
       public void spielt(){   ...   }
       public void registerWaehlen(String register){ ....   }
   }

   ...

   Musikinstrument orgel = new Orgel();
   orgel.spiel();   //  geht
   orgel.registerWaehlen("Kornett")  // geht nicht, obwohl das Objekt vom Typ Orgel ist


Weiterführende Links

Kapitel zu Polymorphie in Java ist auch eine Insel



         


Lehrvideo  (YouTube)