Как правильно использовать дженерики в мастер-классе? - PullRequest
1 голос
/ 24 апреля 2020

У меня есть абстрактный класс под названием 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.

Ответы [ 3 ]

2 голосов
/ 24 апреля 2020

Вот идея:

Имеет интерфейс Sport / абстрактный класс:

interface Sport {

}

и три класса, которые реализуют Sport:

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

Теперь у вас может быть Team<T extends Sport>:

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<Football>, что, я думаю, имеет смысл. Правильно? Во время выполнения Team<Football> должно быть FootballTeam, если вы не пишете больше классов.

Немного отвратительно то, что у вас теперь есть этот странный тип Team<Sport>, но вы не можете создать в любом случае, если вы не напишите больше классов.

1 голос
/ 24 апреля 2020

Спасибо Sweeper и Lonny 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++;
    }

}
1 голос
/ 24 апреля 2020

Полагаю, вы пытаетесь смоделировать Матч внутри Команды. Может быть, вам нужен класс 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

 }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...