简体   繁体   English

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

[英]Access abstract class members from childs inherits

I have an abstract class called Flight and its implement a interface called IFlight and it has a virtual method, another three classes that inherit from it, the only diffrence between those three classes is the implemantation of this method.我有一个叫做 Flight 的抽象类,它实现了一个叫做 IFlight 的接口,它有一个虚方法,另外三个继承自它的类,这三个类之间的唯一区别是这个方法的实现。 Another thing that I want to do is implement a method that accepts as an argument an object of type IFlight (could be one of those three classes) and from them i want to access the members of the abstract class (Flight).我想做的另一件事是实现一个方法,该方法接受 IFlight 类型的对象(可能是这三个类之一)作为参数,然后我想从它们访问抽象类(Flight)的成员。 Which way there is to implement such thing ?有什么方法可以实现这样的事情?

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;
    } 
}

One of the classes (The other two looks similar except the method "Calculate_Price"):其中一个类(其他两个看起来相似,除了方法“Calculate_Price”):

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

Main:主要的:

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]);
}

Your method should accept the type that has the properties it needs, in this case the AbsFlight class.您的方法应接受具有所需属性的类型,在本例中为AbsFlight类。

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

But let's says the method must accept any IFlight .但是假设该方法必须接受任何IFlight In this case, it can't be sure it received an AbsFlight;在这种情况下,不能确定它收到的是 AbsFlight; it has to check.它必须检查。 After the check you can just cast.检查后你就可以施法了。

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

With c#7 there is an additional construct you can use, if you think it is clearer:在 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;
    }
}

It seems to be that you are doing something wrong that this is your requirement.这似乎是你做错了什么,这是你的要求。

When you use an interface and pass it as an argument you want it to be common to all the objects that implement it.当您使用接口并将其作为参数传递时,您希望它对实现它的所有对象都是通用的。

Anyway, if you do want to do it.无论如何,如果你想这样做。 You might do something like:您可能会执行以下操作:

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

Your current solution, in combination with some of the suggestions, will be a case of a mounted riding rider .您当前的解决方案,结合一些建议,将是一个骑乘骑手的情况 You don't need an interface and a base class and testing for type.您不需要接口基类以及类型测试。

You can solve your problem the way you're trying, with a base class and an interface.可以使用基类和接口以您尝试的方式解决问题。 But it's overkill, and you have to kind of duplicate some stuff in the interface and the base class.但这太过分了,你必须在接口和基类中复制一些东西。

You can solve your problem with a simple base class and three derived classes where only Calculate_Price gets overridden.您可以使用一个简单的基类和三个派生类来解决您的问题,其中只有 Calculate_Price 被覆盖。 Put the common items in the base class.将公共项目放在基类中。 This is a very simple solution, easy to figure out, especially if C# and OOP is new to you.这是一个非常简单的解决方案,易于理解,尤其是当您不熟悉 C# 和 OOP 时。

You can also solve your problem with an interface and three classes, not derived.你也可以用一个接口和三个类来解决你的问题,而不是派生的。 This has the disadvantage that you have to implement the interface in three classes.这样做的缺点是您必须在三个类中实现接口。 As Peter Csala points out, C# 8 has some language features that can help minimize this work, possibly making this just as simple as using only a base class and no interface.正如 Peter Csala 指出的那样,C# 8 有一些语言特性可以帮助最大限度地减少这项工作,可能使它像只使用基类而不使用接口一样简单。 I am not too familiar with those features, so I can't judge whether it makes sense.我对这些功能不太熟悉,所以我无法判断它是否有意义。

Then there is another option entirely.然后完全有另一种选择。 This touches on what zaitsman hinted at - that this is possibly an XY problem.这触及了 zaitsman 所暗示的——这可能是一个 XY 问题。 Why do you want to distinguish between Regular, Charter and LowCost using classes derived from Flight/AbsFlight?为什么要使用从 Flight/AbsFlight 派生的类来区分 Regular、Charter 和 LowCost? Is it possible to just have an attribute that tells what price profile is used?是否有可能只有一个属性来说明所使用的价格概况? Are there other fields and properties of a Flight that has nothing to do with the price, and yet also distinguishes flights? Flight 的其他字段和属性是否与价格无关,但也可以区分航班? Perhaps just use one class.也许只使用一个类。

About testing for class type.关于类类型的测试。 This is what we call code smell.这就是我们所说的代码异味。 Generally, if you test for class types a lot, then you defy the purpose of using classes and/or interfaces in the first place.通常,如果您对类类型进行了大量测试,那么您首先违背了使用类和/或接口的目的。

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

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