Interface als Parameter einer abstrakten Methode
dirk2
- java
0 Jens Holzkämper0 dirk20 Jens Holzkämper0 dirk20 Jens Holzkämper0 dirk2
0 MudGuard0 Jens Holzkämper
Hallo,
Baeume.. Wald.
abstract class AbsProvider {
public abstract IGateway getGateway( IResult result )
}
class MyResult implements IResult {
// [..]
}
class MyGateway implements IGateway {
// [..]
}
class MyProvider extends AbsProvider {
@Override
public MyGateway getGateway( MyResult result ) {
}
}
Warum darf ich MyResult, was ja eine Implementierung des Interfaces "IResult" darstellt, nicht als Parameter angeben? MyGateway hingegen als Rueckgabeparameter wird akzeptiert.
Fragend..
Dirk2
Tach,
Warum darf ich MyResult, was ja eine Implementierung des Interfaces "IResult" darstellt, nicht als Parameter angeben?
weil du keine Generics nutzt.
MyGateway hingegen als Rueckgabeparameter wird akzeptiert.
mfg
Woodfighter
Hallo Woodfighter,
weil du keine Generics nutzt.
Aber es handelt sich doch nur um einen Parameter. Sprich weder die Klasse noch der Rueckgabeparameter soll generisch sein. Und so was wie
abstract void DoSth( <Object implements IResult> result )
ist ja nicht machbar.
Danke & Grusz,
dirk
Tach,
Aber es handelt sich doch nur um einen Parameter. Sprich weder die Klasse noch der Rueckgabeparameter soll generisch sein.
die Signatur einer Überschriebenen Methode muß der entsprechen, die du überschreiben willst, die Methode "MyGateway getGateway( MyResult result )" kann ja gar nicht alles, was die Methode "IGateway getGateway( IResult result )" verspricht. Letztere kann alle Objekte die IResult implementieren als Parameter verarbeiten, erstere nur spezielle, dass die Funktion etwas spezielleres zurückgibt ist dabei nicht weiter wild, sie tut damit ja mehr, als sie versprochen hat (der Umkehrschluß wirkt hier nicht, man kann also nicht mit einem Object als Parameter in die andere Richtung verallgemeinern).
Und so was wie
abstract void DoSth( <Object implements IResult> result )
ist ja nicht machbar.
Du möchtest Generics benutzen:
abstract class AbsProvider<T extends IResult> {
public abstract IGateway getGateway( T result );
}
}
class MyProvider extends AbsProvider<MyResult> {
@Override
public MyGateway getGateway( MyResult result ) {
return null;
}
}
mfg
Woodfighter
Hallo woodfighter,
die Methode "MyGateway getGateway( MyResult result )" kann ja gar nicht alles, was die Methode "IGateway getGateway( IResult result )" verspricht.
Doch, sie kann minimum das, was letztere verspricht. Wohlmoeglich kann sie noch viel mehr.
Letztere kann alle Objekte die IResult implementieren als Parameter verarbeiten, erstere nur spezielle,
Ach so, aus dem Blickwinkel betrachtet stimmt deine erste Aussage natuerlich. Und ich glaube genau hier war bei mir der Haken.
abstract class AbsProvider<T extends IResult> {
public abstract IGateway getGateway( T result );
}
}class MyProvider extends AbsProvider<MyResult> {
@Override
public MyGateway getGateway( MyResult result ) {
return null;
}
}
Hm, das ist in meinem Fall/aus meiner Sicht irgendwie eine unschoene Variante. Denn - da es sich um einen Provider handelt - wird das nicht die einzige generische Methode bleiben, sprich IResult wird nicht der einzige dynamische Methodenparameter sein, sondern es werden noch welche hinzukommen.
Vielen Dank
Dirk
Tach,
Hm, das ist in meinem Fall/aus meiner Sicht irgendwie eine unschoene Variante. Denn - da es sich um einen Provider handelt - wird das nicht die einzige generische Methode bleiben, sprich IResult wird nicht der einzige dynamische Methodenparameter sein, sondern es werden noch welche hinzukommen.
es ist problemlos möglich mehrere Typen generisch zu halten oder aber du darfst halt in deinem Interface nicht mehr versprechen, als deine Implementierungen später halten, du kannst ja ein MyResult in eine Funktion stecken, die ein IResult erwartet, aber du kannst dann halt nicht (ohne Casts) auf die spezielleren Eigenschaften zugreifen.
mfg
Woodfighter
Hi Woodfighter,
du kannst ja ein MyResult in eine Funktion stecken, die ein IResult erwartet, aber du kannst dann halt nicht (ohne Casts) auf die spezielleren Eigenschaften zugreifen.
Ja so hatte ich mir das auch schon gedacht, allerdings ist der - meiner Meinung nach sehr erhebliche - Nachteil der, dass nicht bereits auf Compiler-Ebene definiert ist, welche Implementierung eine Methode benoetigt.
Danke & Grusz,
dirk
Hi,
abstract class AbsProvider {
public abstract IGateway getGateway( IResult result )
}class MyResult implements IResult {
// [..]
}class MyGateway implements IGateway {
// [..]
}class MyProvider extends AbsProvider {
@Override
public MyGateway getGateway( MyResult result ) {
}
}
Definieren wir ein weiteres Result:
class NotYourResult implements IResult {
// [..]
}
~~~java
NotYourResult notYourResult = new NotYourResult;
AbsProvider provider = new MyProvider();
provider.getGateway(notYourResult);
sollte dann ja funktionieren - das übergebene Objekt implementiert IResult, paßt also zur Methodendeklaration in AbsProvider.
Aber er paßt nicht zur Methodendeklaration in MyProvider, da das NotYourResult ja keine Ableitung von MyResult ist.
Um diese Situation zu verhindern, darf Deine MyProvider die Methode nicht mit MyResult deklarieren. Zumindest nicht als Override der abstrakten Methode ...
cu,
Andreas
Tach,
Warum darf ich MyResult, was ja eine Implementierung des Interfaces "IResult" darstellt, nicht als Parameter angeben? MyGateway hingegen als Rueckgabeparameter wird akzeptiert.
mal ein anderer Ansatz: Warum steckt in dem IResult eigentlich nicht alles drin, was du brauchst? Klingt als wäre deine Aufteilung suboptimal.
mfg
Woodfighter