繁体   English   中英

从孩子继承访问抽象类成员

[英]Access abstract class members from childs inherits

我有一个叫做 Flight 的抽象类,它实现了一个叫做 IFlight 的接口,它有一个虚方法,另外三个继承自它的类,这三个类之间的唯一区别是这个方法的实现。 我想做的另一件事是实现一个方法,该方法接受 IFlight 类型的对象(可能是这三个类之一)作为参数,然后我想从它们访问抽象类(Flight)的成员。 有什么方法可以实现这样的事情?

航班:

class AbsFlight: IFlight
{ 
    public int ID { get; set; }

    public string Start_Point { get; set; }

    public virtual float Calculate_Price(float Base_Price)
    {
        return Base_Price;
    } 
}

其中一个类(其他两个看起来相似,除了方法“Calculate_Price”):

class Charter: AbsFlight
{
    public override float Calculate_Price(float Base_Price)
    {
        return base.Calculate_Price(Base_Price) * 3;
    }
}

主要的:

private static void Some_Method(IFlight flight)
{
    Console.WriteLine(flight.Calculate_Price(2)); //OK
    Console.WriteLine(flight.ID); //Error
}

static void Main(string[] args)
{
    List<IFlight> flights = new List<IFlight>();

    flights.Add(new Regular());
    flights.Add(new Charter());
    flights.Add(new LowCost());

    Main_SomeMethod(flights[0]);
}

您的方法应接受具有所需属性的类型,在本例中为AbsFlight类。

private static void Some_Method(AbsFlight flight)
{
    Console.WriteLine(flight.Calculate_Price(2)); 
    Console.WriteLine(flight.ID); //OK
}

但是假设该方法必须接受任何IFlight 在这种情况下,不能确定它收到的是 AbsFlight; 它必须检查。 检查后你就可以施法了。

private static void Some_Method(IFlight flight)
{
    Console.WriteLine(flight.Calculate_Price(2)); 
    if (flight is AbsFlight)
    {
        Console.WriteLine(((AbsFlight)flight).ID); //OK
    }
}

在 c#7 中,您可以使用一个额外的构造,如果您认为它更清楚:

private static void Some_Method(IFlight flight)
{
    Console.WriteLine(flight.Calculate_Price(2)); 
    switch (flight)
    {
        case AbsFlight absFlight:
            Console.WriteLine(absFlight.ID); //OK
            break;
    }
}

这似乎是你做错了什么,这是你的要求。

当您使用接口并将其作为参数传递时,您希望它对实现它的所有对象都是通用的。

无论如何,如果你想这样做。 您可能会执行以下操作:

if (flight is Flight)
{
    Flight yourFlight = (Flight)flight;
    // Here you can use anything you need from Flight, e.g: yourFlight.ID
}

您当前的解决方案,结合一些建议,将是一个骑乘骑手的情况 您不需要接口基类以及类型测试。

可以使用基类和接口以您尝试的方式解决问题。 但这太过分了,你必须在接口和基类中复制一些东西。

您可以使用一个简单的基类和三个派生类来解决您的问题,其中只有 Calculate_Price 被覆盖。 将公共项目放在基类中。 这是一个非常简单的解决方案,易于理解,尤其是当您不熟悉 C# 和 OOP 时。

你也可以用一个接口和三个类来解决你的问题,而不是派生的。 这样做的缺点是您必须在三个类中实现接口。 正如 Peter Csala 指出的那样,C# 8 有一些语言特性可以帮助最大限度地减少这项工作,可能使它像只使用基类而不使用接口一样简单。 我对这些功能不太熟悉,所以我无法判断它是否有意义。

然后完全有另一种选择。 这触及了 zaitsman 所暗示的——这可能是一个 XY 问题。 为什么要使用从 Flight/AbsFlight 派生的类来区分 Regular、Charter 和 LowCost? 是否有可能只有一个属性来说明所使用的价格概况? Flight 的其他字段和属性是否与价格无关,但也可以区分航班? 也许只使用一个类。

关于类类型的测试。 这就是我们所说的代码异味。 通常,如果您对类类型进行了大量测试,那么您首先违背了使用类和/或接口的目的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM