c# - 两个接口(interface)和两个类之间的关系。

标签 c# interface class-diagram

所以我想设计这样的团队/球员关系:每个球员都属于一个球队,但由于我想练习界面,所以我制作了 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/

相关文章:

java - 不变性和一般与特定类型

inheritance - 在结构中嵌入两个同名的结构

c# - 使用属性来满足接口(interface)需求

uml - 如何在 UML 类图中描述包含的映射?

java - 如何编写类型来自 Java 中另一个类的构造函数?

c# - 使用反射的比较运算符

c# - 一个属性的get可以是抽象的,而set是虚拟的吗?

c# - 我什么时候应该使用 ServiceFabricIntegrationOptions.UseUniqueServiceUrl

c# - 事实与理论的区别? - xUnit.net

python - 如何为django项目制作类图?