2013-08-05 119 views
0

所以,我想爲android sqlite創建一個小型庫,並且我已經獲得了大部分基本函數,但是我遇到的問題是將結果作爲特定類。我有將泛型投射到它的子類

abstract public class Table<RowClass extends Row>{ 
    public List<RowClass> fetchAll() { 
     //Fetch the stuff here 
     //In the while class to add each row to the array 
     RowClass row = (RowClass) new Row(); 
    } 
} 

但每當我試圖登錄row.getClass()的getName(),它總是回來爲行,而不是RowClass,和它的作用,而不是像RowClass行。我怎樣才能將它投到RowClass?

編輯:什麼表

public class SourcesTable<Rowclass extends Row> extends Table<Row> 
{ 
    public String getName() 
    { return "sources"; } 

    public String[] getAllColumns() 
    { 
     String[] columns = { "name" }; 
     return columns; 
    } 
} 

延伸,我

Tables sourcesTable = new SourcesTable<SourcesRow>(); 
List<SourcesRow> list = sourcesTable.fetchAll(); 

public class SourcesRow extends Row 
{ 
    public String toString() 
    { return this.data.get("name"); } 
} 

而且

public class Row 
{ 
    public String toString() 
    { return ""; } 
} 
初始化它

對不起,如果這是混亂,我正在學習Java來自PHP,所以我可能會繞錯誤的方式,我只是不習慣嚴格類型鑄造

+2

如果RowClass擴展Row,如何將Row投射到RowClass? –

+0

你能告訴我們調用代碼嗎? (即擴展表的類和它的實例化)。我們可能能夠更好地澄清你的誤解 – torquestomp

+0

您的問題措辭不當或我不明白,因爲在我看來,您的問題是擴展問題,而不是泛型。通過「將泛型轉換爲其子類」,你究竟意味着什麼?因爲RowClass本身不是通用的。表和列表是...需要更多的代碼。 –

回答

2

這是你的相關代碼(其餘代碼的你張貼,其實沒必要:)):

abstract public class Table<RowClass extends Row>{ 
    public List<RowClass> fetchAll() { 
     //Fetch the stuff here 
     //In the while class to add each row to the array 
     RowClass row = (RowClass) new Row(); 
    } 
} 

看來,你問的是如何創建的RowClass一個新的實例。你不能。 Java不提供有關RowClass類型的信息。由於類型擦除,有關作爲通用參數傳遞的類型的信息在運行時不存在。如果要實例化泛型參數類型的對象,則必須以另一種方式提供該類。例如(異常處理留下了爲清楚起見):

abstract public class Table<RowClass extends Row>{ 
    private final Class<RowClass> rowClass; // holds the Class of each row 
    public Table (Class<RowClass> rowClass) { 
     this.rowClass = rowClass; 
    } 
    public List<RowClass> fetchAll() { 
     //Fetch the stuff here 
     //In the while class to add each row to the array 
     RowClass row = rowClass.newInstance(); 
    } 
} 

然後通過Whatever.class到表的構造函數(表是抽象的,所以你的情況,你的子類必須自己行的類傳遞給超級構造),例如:

// assume: SpecialRow and MyCustomRow are concrete classes extending Row 
// and defined elsewhere. 

// scenario 1 - subclass knows row type 
public class SpecialTable extends Table<SpecialRow> { 
    public SpecialTable() { 
     super(SpecialRow.class); 
    } 
} 

// scenario 2 - subclass still lets user specify row type 
public class CustomTable <R extends Row> extends Table<R> { 
    public CustomTable (Class<R> rowClass) { 
     super(rowClass); 
    } 
} 

// usage: 
SpecialTable special = new SpecialTable(); 
CustomTable<MyCustomRow> custom = new CustomTable<MyCustomRow>(MyCustomRow.class); 

您也可以通過類來使用fetchall,如:

public List<RowClass> fetchAll(Class<RowClass> rowClass) { 
    //Fetch the stuff here 
    //In the while class to add each row to the array 
    RowClass row = rowClass.newInstance(); 
} 

甚至傳遞一個對象的工作(在精神上通用指定者(多麼相似)),LIK E:

public List<RowClass> fetchAll(RowClass refObject) { 
    //Fetch the stuff here 
    //In the while class to add each row to the array 
    RowClass row = refObject.getClass().newInstance(); 
} 

欲瞭解更多信息:

編輯:還有另外一種設計方法,在這裏,如果我什麼猜測你正試圖做的是正確的。

因爲表是抽象的,所以我得到了一個感覺,即您正試圖創建Table子類,其中子類具有其自己的特定行類型。在這種情況下,上面的第一個選項(將類類傳遞給超級構造函數)將是最合適的。然而,而不是做這一切,你不妨考慮讓子類實例化自己,知行類,並提供一個抽象的方法,它允許基地要做到這一點,如:

abstract public class Table { // no generics necessary 
    // subclasses must override this 
    abstract protected Row newRow(); 
    // the base class can use newRow() to let the subclass determine the type 
    public List<Row> fetchAll() { 
     // in the while loop to add each row to the array: 
     Row row = newRow(); 
    } 
} 

這種方法的主要讓知道其特定Row子類的Table子類構造他們認爲合適的Row子類的好處。

希望有所幫助。

+1

非常感謝。你對我想要做的事完全正確,你的第二個答案更方便,更符合目的。對不起,我試圖從PHP學來構建Android應用程序,所以這有點令人困惑 –

+1

不客氣。我剛剛編輯了上面的答案,添加了一個Table子類的使用示例(上面的SpecialTable和CustomTable示例)。祝你好運!你會發現它。 Java是一門非常乾淨的語言,易於學習。 –