簡體   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