【问题标题】:How can I properly use generics in a master class?如何在大师班中正确使用泛型?
【发布时间】:2020-04-24 11:29:29
【问题描述】:

我有一个名为 Team 的抽象类,从中派生出另外三个名为 FootballTeam、BasketballTeam 和 VolleyballTeam 的类。在基类中,我有一种计算两支球队比赛结果的方法,但我需要一种正确使用泛型的方法,以避免不同运动的球队相互对抗。我显然在这里做错了什么,但我无法弄清楚。

基类:

public abstract class Team<T extends Team<T>> {

    protected String teamName;
    protected Integer won = 0;
    protected Integer lost = 0;
    protected Integer tied = 0;
    protected Integer played = 0;

    public void matchResult(T opponent, Integer homeScore, Integer awayScore) {
        if (homeScore > awayScore) {
            won++;
        } else if (homeScore < awayScore) {
            lost++;
        } else {
            tied++;
        }

        played++;

        if (opponent != null) {
            opponent.matchResult(null, awayScore, homeScore);
        }
    }

}

派生类:

public class FootballTeam extends Team {

    public FootballTeam(String teamName) {
        super(teamName);
    }

    // code
}

public class BasketballTeam extends Team {

    public BasketballTeam(String teamName) {
        super(teamName);
    }

    // code
}

public class VolleyballTeam extends Team {

    public VolleyballTeam(String teamName) {
        super(teamName);
    }

    // code
}

另一种解决方案是在每个子类中实现 matchResult 方法,但这不符合 DRY 原则。

【问题讨论】:

  • public class FootballTeam extends Team&lt;FootballTeam&gt;.

标签: java generics inheritance


【解决方案1】:

这是一个想法:

有一个Sport 接口/抽象类:

interface Sport {

}

以及实现Sport的三个类:

class Football implements Sport {}
class Basketball implements Sport {}
class Volleyball implements Sport {}

现在您可以拥有Team&lt;T extends Sport&gt;

public abstract class Team<T extends Sport> {

matchResult方法需要改成:

public void matchResult(Team<T> opponent, Integer homeScore, Integer awayScore) {

您的具体团队类将像这样声明:

public class FootballTeam extends Team<Football> { ... }
public class BasketballTeam extends Team<Basketball> { ... }
public class VolleyballTeam extends Team<Volleyball> { ... }

采用这种设计,FootballTeam 无法与BasketballTeam 对战,但可以与Team&lt;Football&gt; 对战,我认为这是有道理的。对?在运行时,Team&lt;Football&gt; 必须是 FootballTeam,除非您编写更多类。

这有点丑陋的是,你现在有了这个奇怪的Team&lt;Sport&gt; 类型,但无论如何你都不能创建它的实例,除非你写更多的类。

【讨论】:

    【解决方案2】:

    我猜您正在尝试在团队内部建模比赛。也许你需要一个 Match 类?

    public class Match {
    
     private Team teamOne;
     private Team teamTwo
    
     public Match(Team one, Team two) {
       if (one == null || two == null) {
        throw new IllegalArgumentException("one or both teams are Null");
       }
       if (!one.getClass().equals(two.getClass()) {
        throw new IllegalArgumentException("Both teams must be of the same type");
       }
       this.teamOne = one;
       this.teamTwo = two;
     }
    
     public Team winner() {
      // here you can determine which team wins depending on their class
      if (one instanceof FootballTeam) {
       // ... calculate the winner of a football match
      } 
      // else calculate the winner of the other possibilities
    
     }
    
    }
    

    【讨论】:

      【解决方案3】:

      感谢SweeperLonny Ono 的回答。最后我决定创建一个 League 类并在其中实现 matchResult 方法:

      public class League<T extends Team> {
      
          ArrayList<T> teams;
      
          public League() {
              this.teams = new ArrayList<>();
          }
      
          public boolean addTeam(T team) {
              if (!teams.contains(team)) {
                  teams.add(team);
                  return true;
              } else {
                  return false;
              }
          }
      
          public void printLeagueDetails() {
              for(T team : teams) {
                  team.printTeam();
              }
          }
      
          public void matchResult(T homeTeam, T awayTeam, Integer homeScore, Integer awayScore) {
              if (homeScore > awayScore) {
                  homeTeam.won++;
                  awayTeam.lost++;
              } else if (homeScore < awayScore) {
                  homeTeam.lost++;
                  awayTeam.won++;
              } else {
                  homeTeam.tied++;
                  awayTeam.tied++;
              }
      
              homeTeam.played++;
              awayTeam.played++;
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-21
        • 1970-01-01
        • 2021-09-25
        • 1970-01-01
        • 2022-01-16
        • 2013-04-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多