所以我想设计这样的团队/球员关系:每个球员都属于一个球队,但由于我想练习界面,所以我制作了 ITeam 和 IAthlete,然后制作了 BasketballTeam 和 BasketballPlayer。 然后我写了这段代码:
public interface IAthlete
{
string GetName();
string GetSport();
}
public interface ITeam
{
void AddPlayer(IAthlete player);
IAthlete[] GetAthletes();
string GetName();
int GetNumberOfPlayers();
}
public class BasketballPlayer:IAthlete
{
private string name;
public string GetName()
{
return this.name;
}
public string GetSport()
{
return "Basketball";
}
public BasketballPlayer(string name)
{
this.name = name;
}
public void Run(int distance)
{
Console.WriteLine(this.name + " just ran " + distance.ToString() + " meters.");
}
public bool Shoot()
{
Console.WriteLine("Successful shot for " + this.name);
return true;
}
}
public class BasketballTeam: ITeam
{
BasketballPlayer[] players;
int numberOfPlayers;
private string name;
public void AddPlayer(BasketballPlayer player)
{
this.players[this.numberOfPlayers] = player;
this.numberOfPlayers++;
}
public IAthlete[] GetAthletes()
{
return this.players;
}
public string GetName()
{
return this.name;
}
public int GetNumberOfPlayers()
{
return this.numberOfPlayers;
}
public BasketballTeam(string name)
{
this.numberOfPlayers = 0;
this.name = name;
this.players = new BasketballPlayer[10];
}
}
class Program
{
static void Main(string[] args)
{
BasketballTeam bt = new BasketballTeam("MyTeam");
BasketballPlayer bp = new BasketballPlayer("Bob");
bt.AddPlayer(bp);
foreach (BasketballPlayer player in bt.GetAthletes())
{
Console.WriteLine(player.GetName());
}
foreach (IAthlete a in bt.GetAthletes())
{
Console.WriteLine(a.GetName());
}
}
}
但它不会编译,因为我正在使用这个:
public void AddPlayer(BasketballPlayer player)
在 BasketballPlayer 而不是这个
public void AddPlayer(IAthlete player)
我认为它应该有效,因为 BasketballPlayer 是一名 IAthlete。 如果我将它更改为 IAthlete,那么我可以像这样创建另一个类:
public class HockeyPlayer : IAthlete
{
private string name;
public string GetName()
{
return this.name;
}
public string GetSport()
{
return "Hockey";
}
public HockeyPlayer(string name)
{
this.name = name;
}
public void Run(int distance)
{
Console.WriteLine(this.name + " just ran " + distance.ToString() + " meters.");
}
}
然后在我的主程序中执行此操作:
HockeyPlayer hp = new HockeyPlayer("Henry");
bt.AddPlayer(hp);
这在逻辑上是错误的,因为我将 HockeyPlayer 添加到 BasketballTeam。它应该是这样的,我应该小心不要那样做吗?我究竟做错了什么?我如何使用类图来显示它?这会导致松耦合吗?
最佳答案
您正试图违反 Liskov Substitution Principle .
任何可以用父类(super class)型完成的事情——比如添加一个HockeyPlayer
——也可以用一个子类型来完成——包括一个BasketballTeam
。
相反,您应该使用泛型:
class Team<TPlayer> where TPlayer : IAthlete {
public ReadOnlyCollection<TPlayer> Players { get; }
public string Name { get; }
public void AddPlayer(TPlayer player);
}
关于c# - 两个接口(interface)和两个类之间的关系。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10072598/