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