繁体   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