2009-04-08 17 views
5

Mam klasę podstawową, która ma abstrakcyjną metodę getType(). Chcę, aby podklasy były w stanie zaimplementować tę metodę i zapewnić rzeczywistą klasę do użycia.Zwróć zagnieżdżony typ klasy w języku Java

W kodzie, coś jak następuje:

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

Problem polega na tym, że mam „MyTile nie może zostać rozwiązany” w wierszu oznaczonym. Więc staram się powrócić zamiast tego.

zwrotny nowy MyTile() getClass()

ale teraz Eclipse mówi mi:

niezgodność typów: nie można przekonwertować z Przechwytywanie klasy < # 1-of? rozciąga B.MyTile > do klasy < A.Tile >

który nawet nie jestem pewien, czy nie może to błąd w Eclipse tutaj top (capture # 1?).

Następnie rezygnuję z interfejsów i próbuję użyć abstrakcyjnej podstawowej klasy Tile. Z pomocą Eclipse, I skończyć z następującego kodu, który wydaje się skompilować:

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

Więc w zasadzie wydaje się mieć trzy pytania:

1) jest to możliwe, aby uzyskać to do pracy z .Tile będącym interfejsem?

2) Czy podczas korzystania z klasy bazowej numer Class<? extends X> jest prawidłowy?

3) A w jaki sposób mogę zwrócić moje zagnieżdżone odniesienie do klasy B.MyTile z metody? Zrobić new MyTile().getClass() nie może być w porządku, prawda?

+0

Prawdopodobnie zwracanie "klasy" zamiast nieodblaskowego obiektu jest złym pomysłem. –

+0

@ Tom Zwracanie klasy w kontekście sprawdzanych typów jest bardzo powszechnym wzorcem, który umożliwia sprawdzanie typu * sprawdzonego *, na przykład kolekcji w czasie wykonywania. Nie znam innego sposobu, w rzeczywistości ... – Varkhan

Odpowiedz

6

Nadpisywanie typów ogólnych i kowariantnych nie działa dobrze razem. Musisz jawnie zadeklarować getTileClass() jako zwracającą klasę, która może być podklasą pod nazwą A.Tile.

Możesz także uzyskać dostęp do obiektu klasy MyTile bez jego wstawiania za pomocą MyTile.class.

Spróbuj to zamiast:

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

Jeszcze lepiej byłoby, aby rodzajowe. Nadal trzeba używać rozciąga w definicji typu klasy, ale można być nieco bardziej szczegółowe:

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

prawdopodobnie błąd kopiowania i wklejania, ale czy metoda abstrakcyjna może mieć ciało? poprawna powinna być "chroniona klasa getTileClass {..." –

+0

@ Collos tak, to był nadprogram c/p – Varkhan

+0

Dobra odpowiedź. JEST to problem tylko z powodu kowariancji lub ogólnie? – 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(); 
    } 
} 

Nie potrzeba leków generycznych, po prostu chcę powiedzieć, że wrócisz dachówka lub blachodachówka podklasa.

Nawiasem mówiąc, publiczny interfejs statyczny w klasie to "zapach kodu"; albo uczyń go chronionym, więc tylko podklasy A mogą implementować Tile lub umieścić go we własnym interfejsie najwyższego poziomu. Wrzucenie, ale pozwolenie każdemu na wdrożenie, wysyła mieszaną wiadomość.

Powiązane problemy