2016-11-29 2 views
0

더 좋은 방법이 있는지 궁금합니다. 내가 원한 것은 추상 클래스의 구체적인 메소드가 추상 클래스를 확장하는 구체적인 인스턴스를 리턴하도록하는 것이다. 여기 추상 부모 클래스의 메소드에서 구체적인 하위 클래스의 인스턴스 반환

내가 지금 뭘하는지입니다 :

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

class ChildClass1 extends ParentClass<ChildClass1>{ 
... 
} 
내가이 항상 있기 때문에 T이 캐스팅해야한다고 생각하지 않습니다

는 T.

의 인스턴스입니다
+4

이렇게하기로 결정하면 깨질 것입니다 :'class ChildClass2 extends ParentClass '. 이제는 무엇을 성취하고자하는지, 왜 성취하기를 원하는지에 대해서는 분명하지 않습니다. 그에 따라 질문을 업데이트하고 싶은 경우 답변을 드릴 수 있습니다. –

+0

@JoeC 내가 가지고있는 것은 작동하지만 부모 클래스에서 'this'를 T로 캐스팅해야합니다. 'this'가 T의 인스턴스라는 것을 이미 알고 있어야합니다. 그래서 더 우아한 해결책이 있는지 궁금합니다. 생각할 정도로 똑똑하지 않았습니다. 내가 캐스팅 할 필요가 없거나 제네릭을 사용하지 않고 자식 인스턴스를 반환 한 인스턴스. –

+0

내가 제안한 하위 클래스로 가지고있는 것을 사용해보고 여전히 작동하는지 알려주십시오. –

답변

0

문제는 "이 바로 클래스"의 유형을 참조 할 수있는 방법이 없다는 것입니다. 따라서 abstract class Base<T extends Base<T>>과 같은 구문을 사용해야합니다. 그러나 많은 사람들이 의견에서 언급했듯이 Subclass1 extends <Subclass2>을 정의하는 것을 금지하지 않습니다. T이 "이 매우 클래스"임을 보장하는 구문 방식이 있습니다.

그러나 런타임에이 보증을 적용 할 수 있습니다. TypeTools 또는 다른 방법을 사용하여 사용 된 제네릭 형식을 추출하고 현재 인스턴스에이 유형이 있는지 확인하십시오. 이 클래스는 인스턴스화 할 수

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; 
    } 
} 

: 이것은 아마도 같은 초래

public class Extension1 extends Base<Extension1> {} 

하지만이 아니다 : thisT의 예입니다

public class Extension2 extends Base<Extension1> {} 

Base 생성자 보장 따라서 this ~ T의 캐스트는 안전합니다.