dirk2: Interface als Parameter einer abstrakten Methode

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

  1. 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.

    Kovarianz

    mfg
    Woodfighter

    1. 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

      1. 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

        1. 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  
           
          
          1. 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

            1. 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

  2. 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

    --
    Warum nennt sich Andreas hier MudGuard?
    O o ostern ...
    Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.
  3. 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