用派生类重写属性
本文关键字:属性 重写 派生 | 更新日期: 2023-09-27 18:19:17
我试着把一个大的类分成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() { }
}
您的重写属性必须尊重精确的基类属性的签名。
在您的特定情况下,您需要
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
....
}
注意它与属性名本身重叠:不好,最好更改它以避免将来命名
问题就像Tigran在属性签名中解释的那样。如果你想为每个派生类自定义类型,你可以使用泛型。
public class ServerBattleField : Battlefield<GameType>
{
}
其中Battlefield
为:
public class Battlefield<T>
{
public T Game { get; set; }
}
你可以强制T
从一个基本的Game
类或接口派生。
使用泛型是一个很好的方法,你的战地类将是这样的:
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
功能,使用它的代码只需要知道将其强制转换为正确的类型。
ServerGame
的BattleField
属性的代码,即使它被定义为返回BattleField
对象,它将使用任何派生类的重写功能。