# Polymorphie und Vererbung



## sumatra (16. Jun 2004)

Ich lerne Java und habe was von polymorphie und sonstigen sachen in der art gehört, doch da ich noch nicht so weit mit dem buch bin, als dass ich selber nach lesen könnte, wollte ich hier fragen... Ich kenne polymorphie indirekt von (computer)viren, die das z.t. auch können... kann mir jemand eine erklärung geben bitte? 
mfg


----------



## bygones (16. Jun 2004)

vielleicht hilft dir dieser artikel weiter: http://www.developer.com/tech/article.php/999971

kurzform:
Polymorphismus ist das Verwenden von Methoden mit dem selben namen:

1. Überladen von Methoden
2. Überschreiben einer Methode in der Vererbung
3. Implementieren einer Methode durch ein interface


----------



## meez (16. Jun 2004)

Polymorphie ist das überschreiben von Methoden...


----------



## sumatra (16. Jun 2004)

danke, aber wozu verwendet man das?


----------



## KSG9|sebastian (16. Jun 2004)

```
class figur{
    int radius;
    public abstract double berechneUmfang();
}
class kreis extends figur(){
    public double berechneUmfang(){
        return Math.PI * radius;
    } 

}
class quadrat extends figur(){
    public double berechneUmfang(){
        return 4 * radius;
    }

}
```

dass ist polymorphie und vererbung zusammen

vorteil: in den klassen kreis, quadrat kannst du jedesmal die variable radius verwenden, musst sie aber nicht nochmal deklarieren..![/code]

//Edit: Upsi  war net ganz wach wo ich des geschrieben hab..^^


----------



## alpi (16. Jun 2004)

So ganz unrecht hat er ja net. (polymorphie) Ein Objekt  hat unterschiedliche Erscheinungsformen/Verhalten. Das kann man auch mit dem Überscheiben einer Methode einer Klassen die ein Interface implementiert hat erreichen. Damit kann man mehrere Klassen schreiben, die die selben Fähikeiten haben aber ganz untzerschiedlich reagieren.

hier eine Erklärung auch auf Deutsch http://www.oszhdl.be.schule.de/gymnasium/faecher/informatik/oop/oop_1.5.htm


----------



## bygones (16. Jun 2004)

KSG9|plak hat gesagt.:
			
		

> ```
> class figur{
> int radius;
> public abstract berechneUmfang();
> ...


:noe:  das soll in java so gehen ???? such mal selber deine Fehler (sind ein paar)


----------



## bygones (16. Jun 2004)

zu 1.

schau dir mal ein paar Konstruktoren in der API an. Man verwendet meist Polymorphie um eine Methode in versch. Weise aufrufen zu können

zu 2.
bei vererbung gibt es zwei untersch. polymorphien:

2.1. "Normale" Vererbung:
d.h. in der Oberklasse ist eine Methode implementiert. Deine Klasse will aber diese Methode aber anders implementieren bzw. diese erweitern. Dann kannst du die Methode aus der Oberklasse überschreiben und deinen eigenen Code darin verwenden.

2.1. Abstract Vererbung:
d.h. in der Oberklasse ist eine Methode als abstract definiert - dann muss deine Klasse diese implementieren.

bei beiden muss die Signatur der Methode übereinstimmen....

zu 3:
bei einer Interface implementieren muss die Methode mit selber Signatur implementiert werden.

wenn es Frage zu Vererbung oder Interfaces gibt - würde ich dir raten ein neuen Thread auzumachen ;-)


----------



## sumatra (16. Jun 2004)

danke
wenn ich dich also richtig verstanden habe, was "vererbung" angeht, dann müsste das eine abstrakte vererbung sein:

```
class MusterKlasse
{
    int funktion(void)
    {
        return (1);
    }
}
```

und jetzt eine andere Klasse:

```
public class Klasse
{
    public static void main(String args[])
    {
        MusterKlasse var;
        var = MusterKlasse();
        System.out.println(var.funktion());
    }
}
```

Ist hier also die funktion "funktion" vererbt worden? seh ich das richtig?  :bahnhof: 
mfg


----------



## bygones (16. Jun 2004)

nein - das ist leider komplett falsch.

Du nutzt in dem Fall keine Vererbung. Du erzeugst dir einfach eine Instanz einer Klasse in einer andere Klasse und nutzt dann die Methoden der Instanz....

Vererbung ist:

```
public class SuperKlasse {
   public void doSomething() {
      System.out.println("Ich tue hier was");
   }
}

public class DieKlasse extends SuperKlasse {
}

public class TestKlasse {
  public static void main(String[] args) {
    DieKlasse k = new DieKlasse();
    k.doSomething(); // DieKlasse erbt diese Methode von der SuperKlasse;
  }
}
```

D.h. eine Klasse erbt über das Schlüsselwort _extends_ von einer anderen Klasse und kann deren Methoden (außer private) mitbenutzen ohne sie explizit zu haben....

Abstrakte Verebung ist dann folgendes:

```
public abstract class SuperKlasse {
   public void abstract doSomething();
}

public class DieKlasse extends SuperKlasse {
   public void doSomething() {
     System.out.println("DieKlasse");
    }
}

public class AndereKlasse extends SuperKlasse {
  public void doSomething() {
     System.out.println("AndereKlasse");
  }
}

public class TestKlasse {
  public static void main(String[] args) {
    SuperKlasse k = new DieKlasse();
    k.doSomething(); // hier wird nun die Methode von DieKlasse aufgerufen

    k = new AndereKlasse();
    k.doSomething(); // hier wird nun die Methode von AndereKlasse aufgerufen
  }
}
```

Bei der abstrakten Vererbung ist die Oberklasse eine abstrakte Klasse und die erbenden klassen müssen alle abstracten methoden der klasse implementieren !


----------



## sumatra (16. Jun 2004)

danke =)
wenn ich das jetzt mit der "normalen vererbung" richtig verstanden habe, so kann man theoretisch auch einfach innerhalt der klasse "TestKlasse" eine instanz auf die klasse "SuperKlasse" bilden und dann auf die methode "doSomething" zugreifen, oder? (sry, ich will hier keine neun-mal-klugen alternativen oder verbesserungsvorschläge angeben, ich weiss, dass es hier um's prinzip geht  ich frage nur, damit ich nichts missverstehe) 
mfg


----------



## KSG9|sebastian (17. Jun 2004)

ja, genau 

Wenn du Vererbung verwendest, dann kannst du die Methoden der Superklasse (so nennt man die KLasse von der man erbt) direkt zugreifen, wenn du ne Assoziation erstellst greifst du mit

assoziation.methode()

drauf zu.

Im Allgemeinen sagt man, dass Vererbung v.a. dann verwendet wird, wenn man 1 Superklasse hat, und verschiedene Unterklassen, welche die Superklasse speziallisieren.

Beispiele:

Superklasse: KFZ
Unterklassen: Auto, Motorrad, Roller, PickUp

oder

Superklasse: Kleidungsstück
Unterklassen: Hemd, Krawatte, Hose, T-Shirt, Pullover



Ich hoffe mal, dass das ganze so verständlicher ist.
Ach ja, noch was zum Thema abstracte Methoden in Superklassen,

Beispiel:

Superklasse: Figur
Unterklassen: Kreis, Quadrat

Jetzt schreibt man in der Klasse Figur die abstracte Methode berechneFlaeche(), als Rückgabe einen double Wert.
Dann überschreibt man in der Klasse Kreis, Quadrat die Methode. Jetzt ist natürlich die Frage nach dem Sinn, man könnte ja auch so in beiden Unterklassen diese Methode machen OHNE sie in der Superklasse zu haben.

Vorteil:

Du hast eine Liste von Figuren


```
Figur[] figuren = new Figuren(20);

figuren[0] = new Kreis(..)
.
.
.
```

Wenn du jetzt die Gesamtfläche aller Figuren berechen willst, dann musst du nur ein Element nach dem anderen durchlaufen und berechenFlaeche() aufrufen, ohne zu casten...hättest du die abstracte methode nicht, dann würde dass nicht gehen!


----------



## sumatra (17. Jun 2004)

THX für die ausführliche erklärung 
müssen aber die methoden innerhalb einer klasse, von der geerbt werden soll, als "public" deklariert sein, damit man auf die zugreifen kann?


----------



## bygones (17. Jun 2004)

protected geht auch !


----------



## Illuvatar (17. Jun 2004)

Aus einer Subklasse kann man auf public und protected Methoden zugreifen. Wenn die Subklasse im gleichen Package ist auch auf package private Methoden (=default).

Wenn eine Methode final deklariert ist, kann man sie nicht ableiten.

Edit: 2.


----------



## bygones (17. Jun 2004)

Illuvatar hat gesagt.:
			
		

> Wenn die Subklasse im gleichen Package ist auch auf package private Methoden (=default).


Versteh ich nicht - meinst du wenn in der Oberklasse die Methode private deklariert ist kann die erbende Klasse wenn sie im selben Package ist drauf zugreifen ?
Das ist nämlich falsch. Eine private Methode ist nur in der implementierenden Klasse zugänglich !!

Und private ist nicht default !!


----------



## Illuvatar (17. Jun 2004)

"package private" = nix vor der Methode  


```
class A
{
  void x()
  {}
}
class B extends A  //gleiches Package
{
  public B()
  {
    x();
  }
}
```


----------



## bygones (17. Jun 2004)

ok - verstehe  :lol:  :roll:


----------



## sumatra (17. Jun 2004)

tut mir leid, wenn ich nerven sollte, aber der meiste teil des thread handelt um vererbung (und jetzt weiss ich auch was das ist    ) 
aber was ist genau polymorphie???  :bahnhof: ist es das, wie es klingt, also dass sich das Programm (eigentständig) verändert? 
mfg


----------



## Illuvatar (17. Jun 2004)

Soweit ich weiß, heißt Polymorphie, von mehreren Klassen zu erben, und wird von Java nicht unterstützt.

Oder hab ich das falsch verstanden?


----------



## bygones (17. Jun 2004)

ne nicht ganz:
http://de.wikipedia.org/wiki/Polymorphie_(Programmierung)



> Polymorphie ("Vielgestaltigkeit") bedeutet, dass Funktionen bzw. Methoden einem bestimmten Typ bzw. einer bestimmten Klasse zugeordnet sind, und je nach Typ/Klasse eines bestimmten Objekts die zugehörige Funktion/Methode ausgeführt wird.
> 
> Man unterscheidet zwischen Kompilationszeit-Polymorphie und Laufzeit-Polymorphie. Kompilationszeit-Polymorphie bedeutet, dass der statische Typ des Objekts die aufgerufene Funktion/Methode bestimmt. Dies funktioniert nur für Sprachen mit statischen Typen, und wird typischerweise mit Überladen und generischen Funktionen implementiert.
> 
> Laufzeit-Polymorphie bedeutet, dass die Klasse des Objekts zur Laufzeit bestimmt, welche Methode aufgerufen wird ("späte Bindung"). Diese muss nicht unbedingt identisch mit dem statischen Typ sein (sofern dieser überhaupt existiert). Die Laufzeit-Polymorphie ist einer der wichtigsten Bestandteile der objektorientierten Programmierung.


----------



## sumatra (17. Jun 2004)

also wenn ich das richtig verstanden habe dann wird (bei der laufzeit polymorphie) noch innerhalb des programmdurchlaufs "entschieden" aus welcher klasse welche methoden entnommen werden??? 
mfg


----------



## Isaac (18. Jun 2004)

Ja. Stellen wir uns mal folgendes einfaches Szenario vor


Du schreibst eine Klasse mit der Methode


```
Bonbonbeutel.getAllBonbons()
```


Von dieser Klasse leitest du Klassen ab

WertersEchte extends Bonbonbeutel
NimmZwei extends Bonbonbeutel

In diesen 2 Klassen implementierst du nun auch die Methode



```
WertersEchte.getAllBonbons()
NimmZwei.getAllBonbons()
```

Jetzt gebe ich deinem Programm von aussen einen Bonbonbeutel (Der aber in wirklichkeit, was du nciht weist, ein Werters oder ein Nimm2 Beutel ist). Du weist zum Zeitpunkt der Programmierung ja nicht ob du nun ne Tüte Werters oder Nimm2 bekommst. Aber du eins weist du. Du kannst die Methode getAllBonbons() Aufrufen.

Zur Laufzeit des Programms wird nun entschieden ob die Werters oder die Nimm2 Methode aufgerufen wird. Alle Methoden in Java sind virtuell. Das bedeutet das eine Methode immer von oberster Implementierungsstelle aufgerufen wird. In diesem Fall also entwerder Werters oder Nimm2.

Am einfachsten kann man es sich an einem kleinen Beispeil begreiflich machen.


```
public static void main(String[] args)
{
    String s = "a";
    Object o = (Object)s;
    o.toString();
}
```


Obwohl ich den String auf Object gecastet habe und eigentlich Object.toString() aufrufe wird hier die String.toString() Methode aufgerufen da ich das Object durch den Cast nicht verändert habe und es weiterhin ein String bleibt.


----------



## sumatra (18. Jun 2004)

danke, jetzt weiss ich eigentlich recht genau was vererbung und polymorphie ist  ..obgleich ich mir nicht den vorteil vor augen halten kann, was nun der unterschied ist, wenn man nun die methode getAllBonbons entweder von der klasse "NimmZwei" oder von "WertersEchte" entnehme   :bahnhof:


----------



## Illuvatar (18. Jun 2004)

Nun, dieses Beispiel ist vielleicht nicht sehr sinnvoll. Als anderes Beispiel könnte man aus dem Java3D-API die Klasse

```
public class J3DGraphics2D extends java.awt.Graphics2d
```
nehmen. 5 der 7 Methoden dieser Klasse überschreiben eine Methode von Graphics2d, z.B. die Methode setBackground, und zwar so, dass die Methoden nichts bewirken.
Die Ausgabefläche hat die Methode getGraphics2D(), die eine J3DGraphics2D zurückgibt.
Wenn man jetzt schreibt

```
J3DGraphics2D 3g2 = canvas3d.getGraphics2D();
Graphics g = (Graphics2d)3g2;
g.setBackground (Color.BLACK);
```
würde in manchen Programmiersprachen, die Kompilationszeit-Polymorphie benutzen, die Methode aus Graphics2d benutzen, was aber nicht geschehen soll. Da Java Late-Binding, also Laufzeit-Polymorphie unterstützt, wird bei diesem Codestück die Methode setBackground der Klasse J3DGraphics2D benutzt, es passiert also nichts.


----------



## sumatra (18. Jun 2004)

klingt logisch   
danke
ich hätte da noch eine weitere frage: wieso wird polymorphie bei viren eingesetzt? und wie überhaupt? denn viren werden wohl kaum in java geschrieben und im gegensatz zu anderen programmiersprachen gibt es in java laufzeit-polymorphie (was ich ja erst durch diesen thread herausgefunden habe  ) 

das soll keine aufforderung sein wie man denn eigene viren zusammenbastelt, ich will nur das prinzip wissen, denn das war unter anderem auch der anlass wieso ich mich und hier überhaupt gefragt habe...


----------

