[英]c# polymorphism
我是多态新手,有点挣扎。
我有三节课。 Visit类,它是基类。 然后是交货和提货。
送货和取货都是参观。
我希望能够参考参观课程并讲授送货和接送。
public virtual class Visit
{
private string customerName;
private string customerAddress;
private DateTime arrivalTime;
public string customername
{
//name properties
set { customerName = value; }
get { return customerName; }
}
public string customeraddress
{
//address properties
set { customerAddress = value; }
get { return customerAddress; }
}
public DateTime arrivaltime
{
//time proerties
set { arrivalTime = value; }
get { return arrivalTime; }
}
}
public class Delivery : Visit
/*
* Polymorphism, Delivery is also a visit.
*/
{
private string deliveryAddress;
private string deliveryName;
public string deliveryaddress
{
set { deliveryAddress = value; }
get { return deliveryAddress; }
}
public string deliveryname
{
set { deliveryName = value; }
get { return deliveryName; }
}
public string ToString()
{ //return Delivery details
return deliveryname + " " + deliveryaddress + " " + customername + " " + customeraddress + " " + arrivaltime;
}
}
public class Pickup : Visit
/*
* Polymorphism, pickup is also a visit.
*/
{
public string ToString()
{ //return Pickup details
return customername + " " + customeraddress + " " + arrivaltime.ToString();
}
}
}
首先,您必须从基类中删除virtual
Visit v=new Pickup();
v.customeraddress = "some address";
v=new Delivery();
v.customeraddress = "some address";
如您在上面的示例中看到的, v
是一种Visit
类型,但我允许它指向一个Pickup
或Delivery
实例,该实例的行为与分配的实例类型不同。
如果我正确理解了您的问题...
您的方案是您有一个Visit
对象,并希望根据是Pickup
还是Delivery
来获取详细信息。 只要在运行时创建了Delivery
或Pickup
对象,就可以执行以下操作:
Visit v = GetVisit() //or whatever your method is
if(v.GetType() == typeof(Delivery))
{
Delivery d = v as Delivery;
}
else //Must be Pickup
{
Pickup p = v as Pickup;
}
然后,您可以使用该对象,根据设计,该对象将向您显示Visit变量以及该类的唯一变量。例如, d.customeraddress
如果从现有资源(例如平面文件或数据库)获取Visit对象,则此方法不起作用。 在这种情况下,如果您打算进一步增加分类,则将需要Visit
类中的一个属性,例如bool AmIDelivery
或Enumeration类。 然后,您可以查看此变量并进行相应的操作-但需要先创建投射对象,然后才能使用它。 如果这对您来说是个问题,我可以举个例子。
如果您不希望实例化基类(即, Visit
对象没有意义,它是Pickup
或Delivery
),则可以将基类声明为abstract
而不是virtual
之后,您可以随意使用多态代码。 例如:
List<Visit> visits = new List<Visit>();
visits.Add(new Pickup{ ... some properties set here ...});
visits.Add(new Delivery{ ... some properties set here ...});
// writes out a pickup via a polymorphic call
Console.WriteLine(visits[0].ToString())
// writes out a delivery via a polymorphic call
Console.WriteLine(visits[1].ToString())
但是,如果要使用交付特定的属性,则不能使用该属性,因为即使对引用的对象的类型为Delivery
,例如对visits[0]
的引用都属于Visit
类型。 要使用它们,您需要检查对象的运行时类型,并将它们强制转换为特定的子类型,如下所示:
foreach (Visit visit in visits)
{
if (visit is Delivery)
{
Delivery d = (Delivery)visit;
//delivery specific code here
}
else if (visit is Pickup)
{
Pickup p = (Pickup) visit;
//pickup specific code here
}
else
{
//unknown descendant, panic
}
}
多态意味着可以在派生类中重写基类中的实现。
在您的情况下,除了ToString()
覆盖之外,所有内容都与继承有关。
请注意,在您的代码中,您隐藏了ToString()
方法。 C#允许您将成员添加到具有父类的确切标识符的继承类中,但这不是多态性。
如果整个ToString()
都用overrides
关键字标记,则您的派生类将进行多态处理 :
public override string ToString()
{
return base.ToString(); // Change this line with any custom action
}
其他细节是,类不能是虚拟的,但成员可以。 类可以是regular
(允许多态)或sealed
(不能继承)。
嗯......你知道什么是上溯造型和向下转换 ?
将引用转换为更具体的类型。 例如:
Visit visit = new Delivery();
Delivery delivery = (Delivery)visit; // This is a downcast!
将引用转换为不太具体的类型。 例如:
Visit deliveryTypedAsBaseClass = new Delivery() // This is an upcast!
然后,由于C#是一种静态类型的语言,所以键入意味着类型为Visit
的变量将有权访问其自己的成员。 如果您需要访问Delivery
成员,则需要对其下调!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.