2017-08-29 77 views
1

跟進earlier SO question,現在我想將Fruit收集到一個籃子中,但知道子類型的出路。如何維護Chapel數組中的對象的子類型

class Banana : Fruit { 
    var color: string; 
} 
class Apple: Fruit { 
    var poison: bool; 
} 
class Fruit { 
} 

var a = new Apple(poison=true); 
var b = new Banana(color="green"); 

if (a.type == Apple) { 
    writeln("Go away doctor!"); 
} 

var basketDom = {1..1}; 
var basket: [basketDom] Fruit; 
basket.push_back(a); 
basket.push_back(b); 

for b in basket { 
    writeln(b.type:string); 
} 

這將打印超類型Fruit。我如何從這個籃子中獲得ApplesBananas

+0

我不知道小教堂,但看起來像a和b在進入籃子之前正在投給水果。你似乎想要更多的東西,而不是繼承Fruit。 –

回答

1

快速入侵(除非存在實際的解決方案)將發送一個元組到basket,其中元組將代表(type_of_object, typecasted_object)

您的代碼將因此成爲,

var basketDom = {1..1}; 
var basket: [basketDom] (string, Fruit); 
basket.push_back((a.type:string, a)); 
basket.push_back((b.type:string, b)); 

for b in basket { 
    writeln(b); 
} 

這會給你

(Apple, {poison = true}) 
(Banana, {color = green}) 

此外,您可以訪問使用索引的類型。例如 - b[1]將是該類型和b[2]的對象內容。

要在此之後訪問類變量,如poisoncolor,你可以不喜歡

if (b[1] == "Banana") { 
    var obj = b[2]: Banana; 
    writeln(obj.color); 
} 

相若方式和爲類Apple

+1

您可以使用與C++'dynamic_cast'行爲相似的顯式類型轉換,而不是像'string'一樣攜帶該類型。 '如果b:Apple then writeln(「Apple」,b:Apple);'如果轉換失敗,返回'nil',在條件內解釋爲'false'。 –