簡體   English   中英

C#類繼承

[英]C# Class Inheritance

問候。 我有以下課程:

public class Ship
{
    public enum ValidShips
    {
        Minesweeper,
        Cruiser,
        Destroyer,
        Submarine,
        AircraftCarrier
    }

    public enum ShipOrientation
    {
        North,
        East,
        South,
        West
    }

    public enum ShipStatus
    {
        Floating,
        Destroyed
    }

    public ValidShips shipType { get; set; }

    public ShipUnit[] shipUnit { get; set; }

    public ShipOrientation shipOrientation { get; set; }

    public ShipStatus shipStatus { get; set; }

    public Ship(ValidShips ShipType, int unitLength)
    {
        shipStatus = ShipStatus.Floating;

        shipType = ShipType;

        shipUnit = new ShipUnit[unitLength];

        for (int i = 0; i < unitLength; i++)
        {
            shipUnit[i] = new ShipUnit();
        }
    }
}

我想像這樣繼承此類:

public class ShipPlacementArray : Ship
{

}

這是有道理的。

我想知道的是如何刪除基類的某些功能?

例如:

    public ShipUnit[] shipUnit { get; set; } // from base class

我希望它是:

    public ShipUnit[][] shipUnit { get; set; } // in the derived class

我的問題是如何實現完全隱藏基類shipUnit的代碼?

否則,我將在派生類中最終獲得兩個shipUnit實現。

感謝您的時間。

ShipPlacementArray僅處理一艘船。 但是數組反映了可以放置船的方向。

我想知道的是如何刪除基類的某些功能?

你不知道 這不是繼承的重點。 繼承的重點是繼承基類功能- 所有這些功能-並添加/更改內容。 用於“是”關系,例如,“汽車就是車輛”。

我的問題是如何實現完全隱藏基類shipUnit的代碼?

聽起來您想讓ShipPlacementArray成為多個Ship對象的包裝或容器。 這似乎不應該使用繼承的情況。

問自己一個問題:“ ShipPlacementArray是一種Ship嗎?”

根據我的經驗,每次我想從繼承的類的類中刪除一個屬性時,我的類設計都是有缺陷的。 解決此問題的一種方法是創建一個沒有ShipUnit屬性的新基類,然后兩次繼承該基類,一次是針對具體的Ship類型,一次是針對具體的ShipPlacementArray類型。 在這兩個子類中,您都可以根據需要實現ShipUnit。

您不能使基類的成員在派生類中消失。 在某些情況下,您可以使用派生類中隱藏成員上的new關鍵字來屏蔽隱藏基成員,但是用戶始終可以將您的對象強制轉換回基類(base)instance_of_derived並訪問基班級的成員。

因此,例如,您可以在派生類中執行以下操作:

public new ShipUnit[][] shipUnit { get; set; }

但是我可以做:

((Ship)ShipPlacementArray_instance).shipUnit

這將引用原始的shipUnit。 因此,您可以“隱藏”成員,但不能禁用其功能或可訪問性。

使用C#的修飾符,您可以從基類成員中隱藏繼承的成員。 查看頁面以供參考。

除了其他出色的答案之外,我想說的是,封裝可能是更好的選擇。 通常,我一開始常常以為我想從一個類繼承,后來發現我真的想封裝它。 您只需在私有字段中聲明原始類的新實例即可。 然后,您可以創建公共屬性和函數,這些公共屬性和函數只需調用原始類,如下所示,從而使您可以很好地控制公開的內容。 這也是避免繼承缺點的一種方法,例如增加了復雜性和無法執行多重繼承(有充分的理由):

class SomeNew
{
  private SomeOld someOld = new SomeOld();//could have done this in constructor instead

  public DoSomething()
  {
    someOld.DoSomething();
  }
}

我不知道這只是一個人為的例子,還是一個實際的問題。 但是,我想說這種情況下的繼承是不希望的。 您有Ship和ShipPlacementArray。 最后的“數組”聽起來更像是數組數據類型。 因此,將其帶走,就可以得到ShipPlacement。

在我看來,這聽起來像是某個地點,所以也許它應該是Ship類的成員?

“從類繼承繼承好對象的方法”-如果您要從基類中尋找新的行為,那么無論如何似乎都不想繼承,因為它們是不同的類型。 也許Ship和ShipPlacementArray應該繼承一個公共接口,但是肯定不是從一個公共基類繼承的。 無論您需要使用哪一個接口,都可以使用它-但在需要ShipUnit矩陣的地方,可以顯式使用ShipPlacementArray類型。

您可以使用“新”運算符。

public new ShipUnit[][] shipUnit { get; set; } // in the derived class

您可以使用new關鍵字,如下所示:

public new ShipUnit[][] shipUnit { get; set; }

我不完全了解您要使用繼承建模的內容,但是我確信這是錯誤的工具。 我認為聚合或合成是您所需要的。

您可以使用new關鍵字或在基類的聲明上添加virtual,並在派生類上覆蓋它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM