我正在尝试将我所拥有的大班级分成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() { }
}
答案 0 :(得分:3)
您的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
....
}
请注意,它与属性名称本身重叠:不好,最好更改它以避免将来在命名方面造成混淆
答案 1 :(得分:1)
问题是Tigran在财产签名中解释的。如果要为每个派生类自定义类型,可以使用泛型。
public class ServerBattleField : Battlefield<GameType>
{
}
Battlefield
的位置:
public class Battlefield<T>
{
public T Game { get; set; }
}
您可以强制T
从基础Game
类或接口派生。
不再需要派生该属性。
答案 2 :(得分:1)
使用Generics是一种很好的方法,你的战地类将如下所示:
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);
}
}
答案 3 :(得分:0)
你不能重载只有返回类型不同的东西。这就是原因:
ServerGame oServer = new ServerGame();
BattleField oBF = oServer.BattleField; //No way to know which BattleField property to return.
您可以覆盖具有相同签名的内容,并且由于ServerBattleField
继承自BattleField
,因此返回类型为ServerBattleField
的对象没有问题BattleField
属性。如果需要ServerBattleField
功能,使用它的代码只需知道将其强制转换为正确的类型。
另请注意,访问ServerGame
BattleField
属性的任何代码,即使它被定义为返回BattleField
对象,将使用任何派生类的覆盖功能。