用多态性保持球员在多项运动中得分

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用多态性保持球员在多项运动中得分相关的知识,希望对你有一定的参考价值。

首先,这是针对大学的,所以我无法给出答案,而是解释了为什么我的代码不起作用并且在解决方案方面指向了正确的方向。这必须被视为学习而不仅仅是学习。我还必须更改方法名称等。

所以我有一个玩多种运动的运动员;他可能是BaseballPlayer和/或FootballPlayer,它们是Player的子类。

BaseballSquadFootballSquad是实际的球队,是TeamList的子类。 TeamList有一个阵列列表protected ArrayList<Player> team,存储球队的球员。玩家通过TeamList方法添加到ArrayList:

public void addPlayer(Player player)
    {
        team.add(player);
    }

每个球员类(BaseballFootball)都有自己的积分计数方法,只有pointsgoals不同。出于分配的目的,通过toString()方法访问玩家和他的计票。这些是通过使用TeamList类型的Iterator通过Player打印的。

将玩家添加到多个体育作品中;打印一个团队的球员名单列表。

什么不起作用是打印正确的分数计数。例如,如果我有一支Baseball球队并且我向该球队添加了Football player,那么打印的是球员的goal计数,而不是他的Baseball points

据我所知,在runtime期间,班级类型保持不变,但我需要它能够在某种意义上改变一个球员的级别,因为我希望一个Football球员被认为是一个Baseball球员,如果这是他所玩的运动。

我觉得我在其他代码工作时在某个地方犯了一个愚蠢的错误。无论是那个还是我到目前为止都已经淹没了它。任何帮助都很感激,我很抱歉我无法显示整个代码!

答案

不幸的是,您尝试完成的任务在Java中是可撤消的。玩家的对象只有一个真正的类,你当然可以在多态层次结构上向上或向下投射,但是将一个FootballPlayer投射到BaseballPlayer会导致错误。您可以将棒球运动员与足球运动员一起添加到集合中的原因是Java中的集合是协变的(here解释)。

我可以建议的最接近的解决方案是尝试更复杂的类层次结构,因为Java允许我们一次实现多个接口(与仅扩展一个类的限制相反)。

希望我能以一种方式帮助您自己完成任务。

另一答案

什么不起作用是打印正确的分数计数。例如,如果我有一支棒球队,并且我向该球队添加一名足球运动员,那么打印的是球员的进球数,而不是他的棒球分数。

好吧,这没有任何意义,为什么Football球员会与Baseball联系?在这种情况下,该程序如何区分它应该从Score得到的Player,这样做是否有意义?

如果它在现实世界中没有意义,那么它在虚拟世界中也不太可能有意义

据我所知,在运行期间,类类型保持不变但我需要它能够在某种意义上改变玩家的类,因为我希望足球运动员被认为是棒球运动员,如果这是他所玩的运动。

我猜你的假设是正确的,因为FootballPlayer并没有神奇地改变为BaseballPlayerBaseball不允许你添加任何其他类型的Player然后BaseballPlayers。 FootballPlayer可以打Baseball的唯一方法是,如果他们也是BaseballPlayer

现在,在Java中你可以通过interfaces的用户实现这一点,所以玩家可以玩多项运动,你需要克服的问题,是如何获得Player的特定Sport的分数 - 这个信息应该在哪里保持?它属于Sport还是Player

让我们退后一步,试着看看更大的图景。根据你的描述,你有......

  • 一个Player,可能会发挥零或更多Sports
  • 一个Sport,可能有零个或多个Players(但可能不会有相同的Player一次)。 Sport是特定类型的Player的容器(即BaseballBaseballPlayers的容器)
  • 一个Score,与PlayerSport相关联。你如何管理这取决于你,我建议你直接将ScorePlayer联系起来。

所以,基本概念是:

  • Sport可能包含零个或多个(特定)Players,但可能只包含任何给定Player的单个实例(Fred无法播放Baseball两次)
  • 一个Player可以发挥多个Sports(这可以通过使用interfaces实现),所以弗雷德可以发挥BaseballFootball
  • 对于给定的ScorePlayerSport相关

由于基线要求似乎是Sport需要能够列出Player的得分和(我假设),有可能列出他们所有的Players的Sport得分,让我有意义允许Player管理Score

那么,你可能会想象一个Player“可能”看起来像这样......

public interface Player {
    // Bunch of other functionality...

    public List<Sport> getSports();
    public Map<Sport, Score> getScores();
    public Score getScore(Sport sport);
}

这意味着当你想为给定的Score列出所有Players的Sports时,Sport将循环通过它的ListPlayer并为自己获得Score,也许是这样的......

for (Player player : players) {
    Score score = player.getScore(this);
}

但是如果你想知道给定的Score的所有Sports / Players,你可以直接从Player自己获得这些信息。

这只是一个广泛的想法/概念,试图解耦一些代码并提供一个广泛的基线,您可以从中开发更复杂的关系/数据

多态性不会改变对象的基本类型。它只是允许对象的行为/行为类似于不同类型的对象(混淆)。也就是说,你可以有一个Player表现得像一个BaseballPlayer和一个FootballPlayer

从代码的角度定义上下文,如果它期望一个BaseballPlayer,它只会看到一个BaseballPlayer

interface只是定义了一个对象保证提供的契约,所以如果它implements BaseballPlayer,它保证实现BaseballPlayer界面所需的所有功能,同样可以说FootballPlayer

如果这两个类具有重叠的功能(即getScore),那么你需要能够管理它,以便getScore方法知道它被调用的上下文(这就是我将Sport传递给它的原因),否则你的实现没有希望知道应该传回什么 - 它缺乏背景

以上是关于用多态性保持球员在多项运动中得分的主要内容,如果未能解决你的问题,请参考以下文章

排球计分——三层架构

如何使用 SQL 从每个组中获得最高得分球员?

解决 mySQL 中每个组的最大得分球员

排球计分(三层架构)

找到每个球员最长的连续得分

排球运动规则简介