[英]c# polymorphism property
我有一個簡單的問題。 有一個基類產品。 派生類為Bracelet,Earring和Ring。 但是鈴聲類具有額外的屬性。
我將如何達到該size屬性,並在下面的代碼中的方法中使用它。
public class Product
{
public int id;
public string title;
}
public class Bracelet : Product
{
}
public class Earring : Product
{
}
public class Ring : Product
{
public int size;
}
Product product;
if(category = 1) // this is a Bracelet
{
product = new Bracelet();
}
else if(category = 2) // this is a Earring
{
product = new Earring();
}
else if(category = 3) // Wola, this is a ring
{
product = new Ring();
product.size = 4; // I cant reach size.. I need to assign size of the ring to decrease stock correctly.
}
product.decreaseStock();
只需先在本地聲明值:
else if (category == 3)
{
var ring = new Ring();
ring.size = 4;
product = ring;
}
這樣,您就可以在if
塊中以Ring
訪問變量,但也可以將其分配給更通用的product
變量。
另外,您可以只使用初始化程序語法:
else if (category == 3)
{
product = new Ring { size = 4 };
}
柯克·沃爾(Kirk Woll)的答案可能是最好的,但是另一種解決方案是使用'as'關鍵字:
(product as Ring).size = 4;
或將其投放:
((Ring)product).size = 4;
另外,請確保不要將賦值運算符(=)與相等運算符(==)混淆。 例如,應該為if(category == 3)
您將不得不在Ring中重寫reduceStock方法。
因此,在產品中,首先將減少庫存的方法標記為虛擬。
public class Product
{
public int id;
public string title;
public virtual void DecreaseStock()
{
//your decrease logic here
}
}
然后,在覆蓋方法中放入考慮大小的新邏輯
public class Ring : Product
{
public int size;
public override void DecreaseStock()
{
//your special logic to deal with size here
}
}
您最好通過C#閱讀Jeffrey Richter的CLR。
您不能通過product
引用來引用ring
的屬性,因為CLR不會知道該對象是ring,這就是為什么CLR不允許您更改其大小。 相反,您應該使用:
Ring ring = new Ring();
ring.size = 4;
如果要通過product
引用訪問此屬性,則應在基類中聲明它。
在這種情況下,由於您是在創建Ring
后立即更改尺寸的,因此,解決方法是將其作為Ring
而不是作為Product
來處理:
Ring ring = new Ring();
ring.size = 4;
product = ring;
在我們擁有Product
的情況下,我們知道是可以鑄造的Ring
。 如果實際上是Earring
則將導致運行時錯誤:
Ring ring = (Ring)product;
ring.size = 4;
或更簡而言之:
((Ring)product).size = 4;
如果產品可能是Ring
,可能不是Ring
,並且如果我們想設置size
,我們當然可以測試:
if(product is Ring)
((Ring)product).size = 4;
通常將測試和強制轉換結合在一起是明智的:
Ring ring = product as Ring;
if(ring != null)
ring.size = 4;
大量投放是一個不好的信號。 通常,我們應該在我們關心的級別上處理對象-僅當我們知道它是Product
時才執行Product
事情。 可以幫助實現此目的的一件事是通過重寫來訪問方法或屬性:
public class Product
{
/* leave out other stuff */
public virtual bool NeedsLargeBox
{
get
{
return false; // most products don't
//(this property could also be abstract to force all derived
//classes to decide upon how it operates)
}
}
}
public class Ring : Product
{
public int size;
public virtual bool NeedsLargeBox
{
get
{
return size > 100;
}
}
}
現在,當Ring
本身處理size
,代碼可以處理一堆Product
對象並確定需要多少個大盒子和多少個小盒子,而該代碼不必直接訪問size
(甚至不知道size
,就可以在之前編寫和運行它甚至創建了Ring
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.