2009-04-08 5 views
5

나는 abstract getType() 메소드를 가진 기본 클래스를가집니다. 서브 클래스가이 메소드를 구현하고 사용할 실제 클래스를 제공 할 수 있기를 원합니다. 코드에서Java에서 중첩 클래스 유형을 반환하십시오.

, 다음과 같은 :

public abstract class A { 
    public static interface Tile; 

    protected abstract Class<Tile> getTileClass(); 
} 

public class B extends A { 
    public static class MyTile implements A.Tile { } 

    @Override 
    protected abstract Class<A.Tile> getTileClass() { 
     MyTile t = new MyTile(); // WORKS 
     return MyTile;   // ERROR HERE 
    } 
} 

여기서 문제는 내가 표시 줄에 "MyTile가 해결 될 수 없다"얻을 수 있다는 것입니다. getClass()

반환 새로운 MyTile()하지만 지금은 Eclipse는 나에게 말한다 :. 그래서 나는이 대신을 반환하기 위해 노력하고있어

유형 불일치 : 에서 변환 할 수 없습니다 Class < 캡처 중 # 1? B.MyTile > 는 클래스 < 내가 아마 여기 이클립스의 버그 상단이 있는지조차 확실하지 않다

A.Tile > 확장 (캡처 # 1?).

다음, 나는 인터페이스를 포기하고 추상 기본 타일 클래스를 사용하는 것을 시도하고있다.)

1이이이 작업을 얻을 수 있습니다 :

public abstract class A { 
    public static abstract class Tile; 

    protected abstract Class<? extends Tile> getTileClass(); 
} 

public class B extends A { 
    public static class MyTile exends A.Tile { } 

    @Override 
    protected abstract Class<? extends A.Tile> getTileClass() { 
     return new MyTile().getClass(); // WORKS 
     return MyTile;     // "Cannot be resolved" 
    } 
} 

그래서 나는 기본적으로 세 가지 질문을 갖고있는 것 같다 : 이클립스의 도움으로, 나는 컴파일 보인다 다음 코드와 끝까지 . 인터페이스가되는 타일?

2) 기본 클래스를 사용하는 경우, 정말 Class<? extends X> 갈 수있는 올바른 방법인가?

3) 그리고 내가 어떻게 방법 내부에서 내 중첩 B.MyTile 클래스 참조를 반환 할 수 있습니다? new MyTile().getClass()해야 할 일은 옳을 수 없습니까?

+0

아마도 비 반사 객체 대신'클래스 '를 반환하는 것은 나쁜 생각입니다. –

+0

@Tom 체크 유형과 관련하여 클래스 을 반환하는 것은 매우 일반적인 패턴이므로 런타임에 컬렉션의 * checked * 유형을 확인할 수 있습니다. 나는 실제로 다른 방법을 안다. – Varkhan

답변

6

제네릭과 공변 형 최우선 함께 잘 작동하지 않습니다. 명시 적으로 getTileClass()를 서브 클래스 A.Tile 일 수있는 클래스를 반환하도록 선언해야합니다.

또한 MyTile.class와, 그것을 instanciating없이 MyTile의 클래스 객체에 액세스 할 수 있습니다.

대신을 시도해보십시오

public abstract class A { 
    public static interface Tile; 

    protected abstract Class<? extends Tile> getTileClass(); 
} 

public class B extends A { 
    public static class MyTile implements A.Tile { } 

    @Override 
    protected Class<MyTile> getTileClass() { 
     return MyTile.class; 
    } 
} 

더 나은

은 일반적인을하는 것입니다. 당신은 여전히 ​​ 클래스 유형 정의에 확장 사용해야합니다,하지만 당신은 좀 더 구체적으로 할 수 제네릭에 대한

public abstract class A<T extends A.Tile> { 
    public static interface Tile; 

    protected abstract Class<? extends T> getTileClass(); 
} 

public class B extends A { 
    public static class MyTile implements A.Tile { } 

    @Override 
    protected Class<MyTile> getTileClass() { 
     return MyTile.class; 
    } 
} 
+0

아마도 복사 및 붙여 넣기 오류가 발생하지만 추상 메서드가 몸체를 가질 수 있습니까? 올바른 "보호되어야합니다 클래스 getTileClass {..." –

+0

@ 카를로스 예, 그건 overeager c/p – Varkhan

+0

좋은 대답. 이것은 공분산 때문이거나 일반적으로이 문제입니까? – Uri

-1
public abstract class A { 
    public static interface Tile {}; 

    // I return something that is-a Tile 
    protected abstract Tile getTileClass(); 
} 

public class B extends A { 
    public static class MyTile implements A.Tile { } 

    @Override 
    protected abstract Tile getTileClass() { 
     return new MyTile(); 
    } 
} 

필요, 당신은 단지 당신이 타일이나 타일을 반환 말을하지 않으려는 아강.

또한, 클래스의 공용 정적 인터페이스는 "코드 냄새"이고; 보호를 설정하여 A의 하위 클래스 만 Tile을 구현하거나 고유 한 최상위 인터페이스에 배치 할 수 있습니다. 그러나 누군가가 그것을 구현하도록 허용하는 것은 혼합 된 메시지를 보냅니다.

관련 문제