簡體   English   中英

用Derived類覆蓋屬性。

[英]Override property with Derived class.

我正在嘗試將一個大類分成3個單獨的類:

具有共享功能的基類

具有僅服務器功能的服務器類

具有僅客戶端功能的客戶端類

我遇到的問題是我無法使用派生類重載屬性。

下面,我准備了基類及其對應服務器的代碼示例。

我離某處很遠,但是我希望能夠調用“基類”函數,並且它們可以與重寫的派生類一起使用。

public class Battlefield
{
    public Tile[,] Tiles { get; set; }
    public virtual Game Game { get; set; }

    public Battlefield(int sizeX, int sizeY, Game game)
    {
        Tiles = new Tile[sizeX, sizeY];
        Game = game;
    }

    public Tile GetTile(int x, int y)
    {
        return Tiles[x, y];
    }
}

public class ServerBattleField : Battlefield
{
    public override ServerGame Game  { get; set; }

    public ServerBattleField(int sizeX, int sizeY, ServerGame game) : base(sizeX, sizeY, game)
    {
    }

    public void DoSomethingServerSpecific()
    {
        Game.DoSomethingServerSpecialWithTile(10,5);
    }
}

public class Game
{
    public virtual Battlefield Battlefield {get;set;}

    public Game(int sizeX, int sizeY)
    {
        Battlefield = new Battlefield(sizeX,sizeY,this);
    }

    public void DoSomethingWithTile(int x, int y)
    {
        Battlefield.GetTile(x,y).DoSomethingWithTile();
    }


}

public class ServerGame : Game
{
    public override ServerBattleField Battlefield {get;set;}

    public ServerGame(int sizeX, int sizeY)
        : base(sizeX, sizeY)
    {
    }

    public void DoSomethingServerSpecialWithTile(int x, int y)
    {
        Battlefield.GetTile(x, y).DoSomethingWithTile();
        Battlefield.GetTile(x, y).DoSomethingSpecialWithTile();
    }

}

public class Tile {
    public void DoSomethingWithTile() { }
    public void DoSomethingSpecialWithTile() { }
}

您的ovveriden屬性必須尊重基類屬性的確切簽名。

在您的特定情況下,您需要

public class ServerBattleField : Battlefield
{
    public override ServerGame Game  { get; set; } //CHANGE TO RETURN TYPE GAME

    ....
}

喜歡:

public class ServerBattleField : Battlefield
{
    public override Game Game  { get; set; } //CHANGE TO RETURN TYPE GAME

    ....
}

請注意,它與屬性名稱本身重疊: 不好 ,最好更改它以避免將來在命名上造成混淆

正如提格倫在物業簽名中所解釋的那樣。 如果要為每個派生類自定義類型,則可以使用泛型。

public class ServerBattleField : Battlefield<GameType>
{
}

Battlefield在哪里:

public class Battlefield<T>
{
    public T Game { get; set; }
}

您可以強制T從基本Game類或接口派生。

不再需要繼承該屬性。

使用泛型是一種很好的方法,您的Battlefield類將如下所示:

public class Battlefield<T> where T: Game
{
    public Tile[,] Tiles { get; set; }
    public T Game { get; set; }

    public Battlefield(int sizeX, int sizeY, T game)
    {
        Tiles = new Tile[sizeX, sizeY];
        Game = game;
    }

    public Tile GetTile(int x, int y)
    {
        return Tiles[x, y];
    }
}

public class ServerBattleField : Battlefield<ServerGame> 
{

    public ServerBattleField(int sizeX, int sizeY, ServerGame game)
        : base(sizeX, sizeY, game)
    {
    }

    public void DoSomethingServerSpecific()
    {
        Game.DoSomethingServerSpecialWithTile(10, 5);
    }
}

您不能重載僅返回類型不同的內容。 原因如下:

ServerGame oServer = new ServerGame();
BattleField oBF = oServer.BattleField; //No way to know which BattleField property to return.

您可以覆蓋具有相同簽名的內容,並且由於ServerBattleField繼承自BattleField ,因此從BattleField屬性返回類型為ServerBattleField的對象沒有問題。 如果特別需要ServerBattleField功能,則使用它的代碼僅需知道將其轉換為正確的類型即可。

另外,請注意,任何訪問ServerGameBattleField屬性的代碼,即使被定義為返回BattleField對象,也使用任何派生類的重寫功能。

暫無
暫無

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

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