2009-04-08 19 views
5

Soyut bir getType() yöntemine sahip bir temel sınıfım var. Bu yöntemi uygulayabilmek ve kullanılacak asıl sınıfı sağlamak için alt sınıflar istiyorum. kodundaYuvalanmış sınıf türünü Java'ya döndürme

, aşağıdaki gibi bir şey:

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

Buradaki sorun ben işaretlenmiş doğrultusunda "MyTile çözülemeyen" elde ediyoruz. getClass()

dönüş yeni MyTile() ama şimdi Eclipse bana söyler:. Bu yüzden bu yerine dönmek çalışıyorum

tür uyuşmazlığı: dan dönüştüremiyor Sınıf < yakalama # 1-in? B.MyTile > Sınıf < belki burada Eclipse bir hata üst varsa bile emin değilim

A.Tile > kadar uzanır (yakalama 1.?).

Sonra, ben arayüzleri vazgeçmek ve soyut bir taban Çini sınıfını kullanmaya çalışıyorum.)

1 bu A ile çalışmak için mümkün mü:

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

Yani temelde üç soru var gibi: Eclipse bazı yardımıyla, ben derlemek görünüyor aşağıdaki kodla sona .bir arayüz olarak?

2) bir temel sınıf kullanırken, gerçekten Class<? extends X> gitmek doğru yolu nedir?

3) Ve nasıl yönteme içinden benim iç içe B.MyTile sınıf referansı dönebilir? new MyTile().getClass() yapmak zorunda olmak doğru olamaz mı?

+0

Muhtemelen yansıtıcı olmayan bir nesne yerine bir 'Class' döndürmek kötü bir fikirdir. –

+0

@Tom İşaretli türler bağlamında bir Sınıf Dönen çok yaygın bir desendir; bu, örneğin bir koleksiyonun * kontrol edilen * türünü çalışma zamanında kontrol etmenizi sağlar. Başka hiçbir şekilde bilmiyorum, aslında ... – Varkhan

cevap

6

Jenerik ve eşdeğişkin tip ağır basan bir arada çok iyi çalışmaz. GetTileClass() öğesini, A.Tile'ın alt sınıfı olabilen bir sınıfı döndürme olarak açıkça bildirmeniz gerekir.

Ayrıca MyTile.class ile bunu instanciating olmadan MyTile sınıf nesnesi erişebilirler.

yerine bu deneyin:

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

Daha da iyisi

genel bir hale olacaktır. Hala sınıf tipi tanımında uzanır kullanmak zorunda, ancak biraz daha spesifik olabilir: jenerik için

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

muhtemelen kopyala & yapıştır hata, ama soyut bir yöntem bir vücuda sahip olabilir? Doğru "korunan Sınıf getTileClass {..." –

+0

@Carlos evet olmalı, bu bir aşırı c/p – Varkhan

+0

İyi cevap oldu. Bu sadece kovaryanstan mı yoksa genel olarak mı? – 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(); 
    } 
} 

gerek yok, sadece bir Çini veya Çini dönmek olduğunu söylemek istiyorum alt sınıf.

Bu arada, bir sınıfında ortak bir statik arayüzü "kod koku" olduğu; ya korumalı olsun, bu yüzden sadece A'nın alt sınıfları Çini uygulayabilir veya kendi üst düzey arayüzüne yerleştirebilir. Birinin içine koyulması, ancak herkesin uygulamaya koymasına izin vermek, karışık bir mesaj gönderir.

İlgili konular