2016-11-29 2 views
0

Ich frage mich, ob es einen besseren Weg gibt, dies zu tun. Ich möchte eine konkrete Methode in einer abstrakten Klasse haben, die die konkrete Instanz zurückgibt, die die abstrakte Klasse erweitert.Zurückgeben einer Instanz der konkreten untergeordneten Klasse aus einer Methode in der abstrakten übergeordneten Klasse

Hier ist, was ich tue jetzt:

abstract class ParentClass<T extends ParentClass> extends RelativeLayout { 
    ... 
    public T aMethod(){ 
     return (T)this; 
    } 
} 

und

class ChildClass1 extends ParentClass<ChildClass1>{ 
... 
} 

ich ich das T werfen müssen, da diese immer eine Instanz von T. nicht denken sollte, ist

+4

Das wird brechen, wenn ich mich dazu entscheide: 'Klasse ChildClass2 erweitert ParentClass '. Jetzt weiß ich nicht genau, was Sie erreichen wollen oder warum Sie es erreichen wollen. Wenn Sie Ihre Frage entsprechend aktualisieren möchten, könnte ich Ihnen eine Antwort geben. –

+0

@JoeC Was ich habe funktioniert, aber es verlangt von mir, 'dies' in der Elternklasse zu T zu werfen. Es sollte bereits wissen, dass 'dies' eine Instanz von T ist, also habe ich mich gefragt, ob es eine elegantere Lösung gab Das war einfach nicht schlau genug, um daran zu denken. Entweder für eine, bei der ich nicht casten musste, oder für eine, die die Kind-Instanz ohne generische Verwendung zurückgab. –

+0

Versuchen Sie, was Sie mit der von mir vorgeschlagenen Unterklasse haben und lassen Sie mich wissen, ob es noch funktioniert. –

Antwort

0

Das Problem ist, dass es keine Möglichkeit gibt, den Typ von "dieser Klasse" zu referenzieren. Aus diesem Grund müssen Sie Konstrukte wie abstract class Base<T extends Base<T>> verwenden. Aber wie so viele in den Kommentaren erwähnt, verbietet Ihnen nichts, Subclass1 extends <Subclass2> zu definieren. Es gibt gerade jetzt syntaktischen Weg, um zu garantieren, dass T "diese Klasse" ist.

Sie können diese Garantie jedoch in der Laufzeit erzwingen. Sie können etwas wie TypeTools oder andere Methoden verwenden, um den generischen Typ zu extrahieren und sicherzustellen, dass die aktuelle Instanz diesen Typ hat. Dies würde wahrscheinlich in so etwas wie:

public abstract class Base<T extends Base<T>> { 

    protected Base() { 
     final Class<?> t = (Class<?>) ((ParameterizedType) getClass().getGenericSuperclass()) 
       .getActualTypeArguments()[0]; 
     if (!t.isInstance(this)) { 
      throw new IllegalArgumentException(); 
     } 
    } 

    public T getInstance() { 
     @SuppressWarnings("unchecked") 
     T thisIsT = (T) this; 
     return thisIsT; 
    } 
} 

Diese Klasse instanziiert werden kann:

public class Extension1 extends Base<Extension1> {} 

Aber dies nicht:

public class Extension2 extends Base<Extension1> {} 

Die Base Konstruktor garantiert, dass this ist Instanz von T daher ist der Abguss von this bis T sicher.

Verwandte Themen