# Methoden der Unterklasse in Oberklassen-Datentyp anwenden



## p-flash (22. Aug 2005)

Hi,


```
Oberklasse k = new Unterklasse();
```

Wenn ich jetzt zB k.methodeDerUnterKlasse(); anwenden möchte klappt es nicht, da der Typ von der Oberklasse ist.
Wie kann man für diesen einen Methoden-aufruf das Objekt casten? 

Schonmal danke.

p-flash


----------



## schmalhans (22. Aug 2005)

```
Unterklasse k = new Unterklasse();
```

So muss das richtig heißen.

dann einfach:


```
k.methodeDerUnterKlasse();
```


Oder Cast:


```
Oberklasse o = (Oberklasse)k;
```


----------



## p-flash (22. Aug 2005)

Man kann doch jede Unterklasse dort benutzen wo eine Oberklasse einsetzbar ist oder? Dann sind nur die Methoden abrufbar, die der Oberklasse gehören.

p-flash


----------



## schmalhans (22. Aug 2005)

Ja, deswegen nennt man das ganze Vererbung.


----------



## Jörg (22. Aug 2005)

Aber du kannst nicht mit der Oberklasse auf Methoden der Unterklasse zugreifen, wenn diese fremd fuer die Oberklasse sind, spricht dort nicht vorgesehen sind ...


```
O o = new U();
		...
		U u = (U) o;
		u.unterklassenmethode();
```
ist etwas sinnfrei, funktioniert aber ..., nur woher willst du
wissen, dass zu bestimmten Zeitpunkten in o auch wirklich ein
u steckt...??


----------



## p-flash (22. Aug 2005)

Ich dachte da gibt es vllt sowas wie instanceof. Ich kenne das von Flash.


```
if(o instanceof U)
 // rufe die methode der Unterklasse auf.
```

Oder gibt es das bei java nicht?


----------



## schmalhans (22. Aug 2005)

Nicht das ich wüsste.
Das Casten geht mit einem: (Oberklasse) Aber es ist wirklich sinnfrei es zur Oberklasse zu casten, nur um auf die O-Funktionen zuzugreifen. Da wäre die Vererbung umsonst.


----------



## Sky (22. Aug 2005)

Also, 
1.) Man kann von U nach O casten
2.) Man kann mit instanceof arbeiten
3.) Es macht wirklich keinen Sinn: Entweder ich arbeite mit O (und benutze nur dessen Methoden) oder ich arbeite direkt mit U.


----------



## bygones (22. Aug 2005)

Sky hat gesagt.:
			
		

> 3.) Es macht wirklich keinen Sinn: Entweder ich arbeite mit O (und benutze nur dessen Methoden) oder ich arbeite direkt mit
> U.


das ist der entscheidende Punkt. Warum die Oberklasse nehmen, wenn du Methoden der Unterklasse verwendest ? das ist unsinnig.


----------



## schmalhans (22. Aug 2005)

jo, richtig.

entweder wir verstehen p-flash falsch oder es ist wirklich unsinnig.


----------



## p-flash (22. Aug 2005)

Hehe...also ich hatte mir ungefähr soetwas gedacht:

Die Klasse OberK hat zum Beispiel mehrere Unterklassen.

Und in einer anderen Klasse gibt es die Methode:

```
public boolean machWas(OberK o)
{
    o.getDies();
    o.setDas();
    if(o instanceof U)
       return o.eigeneMethodeVonU();
    return o.gemeinsameMethode();
}
```

Hier wird für jede Unterklasse das gleiche gemacht. Handelt es sich um eine Instanz von U, dann wird ein anderer Rückgabewert zurückgegeben. So muss ich nicht eine extra Methode schreiben, die U als Parameter hat.

p-flash


----------



## Sky (22. Aug 2005)

Dann schreib doch ne Methode 'machWas' in O und überschreib sie -bei Bedarf- in deinen Unterklassen.

Ein Beispiel: 
	
	
	
	





```
class TestKlasse {
  public static void main( String[] args )  {
   SuperKlasse s1 = new SuperKlasse();
   s1.machWas();

   SuperKlasse s2 = new UnterKlasse1();
   s2.machWas();

   SuperKlasse s3 = new UnterKlasse2();
   s3.machWas();
  }
}


class SuperKlasse {
  public void machWas() {
    System.out.println( "machWas von SuperKlasse" );
  }
}

class UnterKlasse1 extends SuperKlasse {
  public void machWas() {
    System.out.println( "machWas von UnterKlasse1" );
  }
}

class UnterKlasse2 extends SuperKlasse {
}
```
 und die Ausgabe sieht so aus: 
	
	
	
	





```
machWas von SuperKlasse
machWas von UnterKlasse1
machWas von SuperKlasse
```


----------



## p-flash (22. Aug 2005)

Normalerweise würde das klappen, aber nehmen wir mal an wir haben eine Klasse Raumschiff. Von der Klasse erben SchwachesSchiff und StarkesSchiff.

Die Klasse Raumschiff hat die Methode bekommeSchaden()

StarkesSchiff hat noch die Methode bekommeSchutzschildSchaden()
(die namen sind bischen blöd gewählt).

Dann steht bei der Methode


```
public void machSchaden(Raumschiff r)
{
    r.setGetroffenVon(this);
    if(r instanceof StarkesSchiff)
         r.bekommeSchutzschildSchade();
    else
       r.bekommeSchade();
}
```

Ich weiß das man das irgendwie umschreiben kann, aber das wäre sehr praktisch so.

p-flash


----------



## mic_checker (22. Aug 2005)

dann schreib die methode in die oberklasse und in StarkesSchiff überschreibst du sie so das sie nen Wert zurückliefert (oder was die methode auch immer machen soll).


----------



## Sky (22. Aug 2005)

Wo ist dein Problem?? Ich habe mal nach den Code nach deinen Namen geändert (Logik bleibt aber die gleiche):

```
class TestKlasse {
  public static void main( String[] args )  {
   Raumschiff s1 = new Raumschiff();
   s1.bekommeSchaden();

   Raumschiff s2 = new SchwachesSchiff();
   s2.bekommeSchaden();

   Raumschiff s3 = new StarkesSchiff();
   s3.bekommeSchaden();
  }
}


class Raumschiff  {
  public void bekommeSchaden() {
    System.out.println("Hier macht die Methode nix...");
  }
}

class SchwachesSchiff  extends Raumschiff {
  public void bekommeSchaden() {
    System.out.println( "habe einen grossen Schaden" );
  }
}

class StarkesSchiff extends Raumschiff {
  public void bekommeSchaden() {
    System.out.println( "habe einen kleinen Schaden" );
  }

}
```


----------



## p-flash (22. Aug 2005)

Hmm...ok, ich werde schon irgendwie machen. ist nur etwas ungewohnt.

Danke für die Hilfe.

p-flash


----------



## Sky (22. Aug 2005)

p-flash hat gesagt.:
			
		

> Hmm...ok, ich werde schon irgendwie machen. ist nur etwas ungewohnt.
> 
> Danke für die Hilfe.
> 
> p-flash


Vorteil an der Variante ist einfach: Wenn Du noch mehr "Schiffe" (sprich Unterklassen) bekommst, so musste nicht mit 1000 if-Abfragen arbeiten, sondern die Logik liegt immer da, wo sie hingehört: In dem "Schiff" (der Klasse natürlich) welches den Schaden bekommt...

Auch, wenn's für'n Anfänger ungewöhnlich aussieht (auch wenn ich nicht verstanden habe, was daran ungewohnt ist)


----------



## schmalhans (22. Aug 2005)

Sky hat gesagt.:
			
		

> Vorteil an der Variante ist einfach: Wenn Du noch mehr "Schiffe" (sprich Unterklassen) bekommst, so musste nicht mit 1000 if-Abfragen arbeiten, sondern die Logik liegt immer da, wo sie hingehört: In dem "Schiff" (der Klasse natürlich) welches den Schaden bekommt...



Ist nicht genau das der Vorteil von Vererbung? Wenn es nicht so wäre, wäre ja Vererbung fürn "Po".


----------



## p-flash (22. Aug 2005)

Ungewohnt es weil ich es von Flash anders kenne und davon halt auch öfters gebraucht gemacht habe. Den Sinn der Vererbung habe ich schon verstanden.

Aber (vielleicht ist mein Kopf zu sehr Flash orientiert) es gibt zB Situation wo mein Schiff einfach nur schaden bekommt. Ist es zB in einem anderen Level sollen noch zu zusätzlich 10 andere Methoden aufgerufen werden. Das soll nur bestimmte unterklassen gelten. Und das ist bei allen zb 20 Leveln anders. Dann müsste ich ja theoretisch in der unterklassen methode 20 if-abfragen machen:


```
if(level == 1)...
if(level == 2)...
etc...
```

Dann finde ich sieht man den Vorteil (den zB Flash bietet). Aber wie gesagt, ich programmiere ziemlich intensiv mit Flash und deshalb ist das eine andere Kultur, an der ich mich gewöhnen muss. Oder sieht ihr den Vorteil jetzt auch??  :lol: 

p-flash


----------



## Sky (22. Aug 2005)

Du könntest alternativ auch den Schaden von der Unterklasse in Abhängigkeit vom Level zurück geben lassen:


```
public int getSchaden( int level ) {
  //...
}
```

und dann in der Obklassen sagen: 
	
	
	
	





```
computeSchaden( int schaden ) {
  //...
}
```


----------



## PyroPi (22. Aug 2005)

Ich glaub das Ausgangsproblem sollte mit Castings aber funktionieren:


```
public boolean machWas(OberK o)
{
    o.getDies();
    o.setDas();

    if(o instanceof U)
       return ((U)o).eigeneMethodeVonU();
    if(o instanceof X)
       return ((X)o).eigeneMethodeVonX();

    return o.gemeinsameMethode();
}
```


----------



## Sky (22. Aug 2005)

PyroPi hat gesagt.:
			
		

> Ich glaub das Ausgangsproblem sollte mit Castings aber funktionieren


Die Funktionsweise wurde hier nicht bestritten...


----------



## p-flash (22. Aug 2005)

Aber das habe ich doch die ganze Zeit gefragt:



> Wenn ich jetzt zB k.methodeDerUnterKlasse(); anwenden möchte klappt es nicht, da der Typ von der Oberklasse ist.
> Wie kann man für diesen einen Methoden-aufruf das Objekt casten?



Dann geht es ja doch. Das hatte mich schon sehr gewundert. Dann ist das Problem ja gelöst.

Danke.

p-flash


----------



## Jörg (22. Aug 2005)

> Aber das habe ich doch die ganze Zeit gefragt:


und ich hab dir doch geantwortet!??

```
U u = (U) o; 
u.unterklassenmethode();
```

einzig instanceof hat noch gefehlt ... 
(hier wuerde ne ClassCastException geworfen werden)

wobei mir das immernoch nicht gefaellt. 
Normalerweise wuerde ich das so aehnlich machen (wie Sky bereits vorgeschlagen):

```
class Oberklasse { 
   void bekommeSchaden(){}
 }

 class Unterklasse extend Oberklasse {
   void bekommeSchaden() // ueberschreibt Oberklasse
   {
        spezifischerSchaden();
   }
   void spezifischerSchaden(){..}
 }
```

sonst endest du in instanceof-Bergen, was nicht der Sinn sein kann, 
afaik sind die eh recht teuer ...


----------



## p-flash (22. Aug 2005)

Die Frage war ja nach einem einmaligen Casting, also nur für diesen einen Methodenaufruf, wobei euer Verfahren wahrscheinlich wohl besser ist. Naja, ich muss noch einiges lernen.

Danke.

p-flash


----------

