2016-03-14 53 views
2

我有這5個類。一個叫做Figura的基類是一個抽象類和4個具體派生類。調用派生類的非繼承方法

Classes

我要創建大小爲8的Figuras(二誇德拉多,二Rectangulo,二Triangulo和兩個Circulo)的陣列,所以我這樣做:

Figuras[] figuras = new Figuras[8]; 
figuras[0] = new Cuadrado(1); 
figuras[1] = new Cuadrado(2); 
figuras[2] = new Rectangulo(2, 1); 
figuras[3] = new Rectangulo(6, 2); 
figuras[4] = new Triangulo(1, 2, 2); 
figuras[5] = new Triangulo(3, 3, 4); 
figuras[6] = new Circulo(1); 
figuras[7] = new Circulo(4); 

然後我遍歷該數組計算每個圖的面積和周長。當我嘗試調用僅屬於Circulo數字的方法calcularDiametro()時,問題就出現了。我怎樣才能做到這一點?

我試過以下,但它不起作用。

foreach (Figuras f in figuras) 
    if (f is Circulo) 
     f.calcularDiametro(); 

任何幫助,將不勝感激。

+1

只是一個建議 - 在命名變量,類,方法等時使用英語。註釋也是如此。儘管你在這裏做的事情是可以理解的,但它在國際團隊中不會被接受。 – Filkolev

+0

謝謝你的建議@Filkolev,我真的這樣做。這只是練習在類之間進行鑄造的練習 – IvnBam

回答

4

你需要將其轉換爲Circulo爲了調用Circulo特異性方法:

foreach (Figuras f in figuras) 
{ 
    if (f is Circulo) 
     (Circulo)f.calcularDiametro(); 
} 

注意,這是一個有點浪費,因爲它的類型檢查的兩倍(這是一個代價高昂的操作)。要做到這一點不浪費的一種方法是使用as

foreach (Figuras f in figuras) 
{ 
    Circulo circ = f as Circulo; 
    if (circ != null) 
    { 
     circ.calcularDiametro(); 
    } 
} 
4

您可以使用as算子的,並防止額外的演員和提高性能

foreach (Figuras f in figuras) 
{ 
    var c = f as Circulo; 
    if (c != null) 
     c.calcularDiametro(); 
} 

您還可以使用OfType得到特定類型的對象從你的Enumerable

foreach (var c in figuras.OfType<Circulo>()) 
{ 
    c.calcularDiametro(); 
} 
1

其他答案在技術上是正確的,但錯了。你的問題是你不應該首先從課堂外進行計算。類本身應根據需要執行計算,無論是在構造函數中還是在外部組件請求perimetro或diametro的值時。這是封裝。

+0

封裝是隱藏計算的內部工作。這些課程都做得很好。在我看來,'calcularDiametro'方法不適用於其他形狀,所以對於只有特定的子類才具有此方法,這是完全正確的。 – Enigmativity

+0

我相信馬丁是非常正確的,設計打破了一些原則。 – Glenner003

+0

謝謝Glenner。詳細說明:隱藏計算代碼但要求客戶端啓動計算對於OOP來說是毫無意義的。您對計算不感興趣,您只對perimetro和diametro感興趣(形狀的屬性)。任何需要完成的事情都應該隱藏起來。這就像去麪包店,不要求一個麪包,而是告訴男人把麪糰放入一個形狀,放入烤箱,等待幾個小時,拿出來,放進一個袋子裏,然後遞給它給你。現在誰在做麪包? –