34 Stimmen

Java-Schnittstellen und Rückgabetypen

Stellen Sie sich vor, ich habe die folgende Schnittstelle:

public interface A { public void b(); }

Aber ich möchte, dass jede der Klassen, die sie implementieren, einen anderen Rückgabetyp für die Methode b() haben.

Beispiele:

public class C { 
  public C b() {} 
}

public class D { 
  public D b() {} 
}

Wie würde ich meine Schnittstelle definieren, damit dies möglich wäre?

52voto

Matt McHenry Punkte 19043

Wenn der Rückgabetyp der Typ der Klasse sein muss, die das Interface implementiert, dann handelt es sich um einen sogenannten F-bounded Typ:

public interface A>{ public T b(); }

public class C implements A{
  public C b() { ... }
}

public class D implements A{
  public D b() { ... }
}

Im Klartext deklariert A einen Typparameter T, der den Wert jedes konkreten Typs annimmt, der A implementiert. Dies wird in der Regel verwendet, um Dinge wie clone() oder copy()-Methoden mit starken Typen zu deklarieren. Als weiteres Beispiel wird dies von java.lang.Enum verwendet, um zu deklarieren, dass die geerbte compareTo(E)-Methode jedes Enums nur auf andere Enums dieses speziellen Typs anwendbar ist.

Wenn Sie dieses Muster oft genug verwenden, werden Sie auf Szenarien stoßen, in denen this vom Typ T sein muss. Auf den ersten Blick mag es offensichtlich erscheinen, dass es das ist1, aber Sie müssen tatsächlich eine abstract T getThis()-Methode deklarieren, die Implementierer trivial als return this implementieren müssen.

[1] Wie Kommentatoren angemerkt haben, ist es möglich, etwas Listiges wie X implements A zu tun, wenn X und Y ordnungsgemäß kooperieren. Das Vorhandensein einer T getThis()-Methode zeigt noch deutlicher, dass X die Absichten des Autors des A-Interfaces umgeht.

37voto

Cam Punkte 14515

Generics.

public interface A{
    public E b();
}

public class C implements A{
    public C b(){
        return new C();
    }
}

public class D implements A{
    public D b(){
        return new D();
    }
}

Suchen Sie nach Generics für weitere Details, aber im Grunde passiert folgendes: A lässt den Typ von E den implementierenden Klassen (C und D) über.

Also weiß und muss A im Grunde genommen nicht wissen, was E in einer bestimmten Implementierung sein könnte.

2voto

meriton Punkte 65030

Da Java kovariante Rückgabetypen unterstützt (seit Java 1.5), kannst du Folgendes tun:

public interface A { public Object b(); }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X