簡體   English   中英

c#多態性

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM