C# 多态性属性
本文关键字:属性 多态性 | 更新日期: 2023-09-27 18:37:10
我有一个简单的问题。有一个基类产品。并派生出手镯、耳环和戒指等类别。但是环类有一个额外的属性。
我将如何达到该大小属性并在以下代码的方法中使用它。
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(类别 == 3)
你将不得不覆盖 Ring 中的 reductionStock 方法。
因此,在产品中,首先将减少库存方法标记为虚拟。
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。
您不能通过引用来引用ring
的属性product
因为 CLR 不知道这个对象是环,这就是 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
,也可能不是,并且我们想设置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
(甚至不知道它,它可以在创建之前编写和工作Ring
)。