Java 实现子类的泛型类
我创建了一个运动员班Java 实现子类的泛型类,java,oop,generics,Java,Oop,Generics,我创建了一个运动员班 public class Athlete { private final int id; private final String name; private final Country sourceCountry; public Athlete(int id, String name, Country sourceCountry){ this.id = id; this.name = name;
public class Athlete {
private final int id;
private final String name;
private final Country sourceCountry;
public Athlete(int id, String name, Country sourceCountry){
this.id = id;
this.name = name;
this.sourceCountry = sourceCountry;
}
}
然后我创建了以下接口和子类:
public interface IJumper {
public double jump();
}
此外,我创建了以下RunnerJumper类来创建另一种既能跑又能跳的运动员类型:
public class RunnerJumper extends Athlete implements IRunner, IJumper {
public RunnerJumper(int id, String name, Country sourceCountry) {
super(id, name, sourceCountry);
}
@Override
public double jump() {
return Math.random();
}
@Override
public double run() {
return Math.random();
}
}
现在,我想创建一个团队类。团队应为跑步者或跳跃者团队(跑步者团队可包含跑步者和跳跃者,跳跃者团队可包含跳跃者和跳跃者)
所以我希望团队是通用的。。
此外,团队课程应该有类似“竞争”的方法(
例如:对于团队中的每个运动员:
跑或跳(取决于运动员的类型)
)
我怎样才能达到这种行为
我试着这样做:
public class Team<C extends Athlete> {}
让IRunner和IJumper都扩展它。。
一开始这似乎很好:
public class Team<C extends Competitor> {}
公共类团队{}
但是我不明白如何在这种形式下实现Competite功能…您可以创建两个团队课程,一个用于跑步者,另一个用于跳跃者,如下所示:
public interface Team {
public void compete();
}
public class TeamRunners implements Team {
private List<Runner> runners;
private List<RunnerJumper> runnerJumpers;
public Team(List<Runner> runners, List<RunnerJumper> runnerJumpers) {
this.runners = runners;
this.runnerJumpers = runnerJumpers;
}
@Override
public void compete() {
for (Runner runner : runners) {
runner.run();
}
for (RunnerJumper runnerJumper : runnerJumpers) {
runnerJumper.run();
runnerJumper.jump();
}
}
}
public class TeamJumpers implements Team {
private List<Jumper> jumpers;
private List<RunnerJumper> runnerJumpers;
public Team(List<Jumper> jumpers, List<RunnerJumper> runnerJumpers) {
this.jumpers = jumpers;
this.runnerJumpers = runnerJumpers;
}
@Override
public void compete() {
for (Jumper jumper : jumpers) {
jumper.jump();
}
for (RunnerJumper runnerJumper : runnerJumpers) {
runnerJumper.run();
runnerJumper.jump();
}
}
}
公共接口团队{
公开无效竞争();
}
公共类TeamRunners实现团队{
私人名单;
私人跑步运动员名单;
公共团队(名单上的跑步者,名单上的运动员){
这个。跑步者=跑步者;
this.runnerJumpers=runnerJumpers;
}
@凌驾
公开竞逐(){
用于(跑步者:跑步者){
runner.run();
}
用于(RunnerJumper RunnerJumper:runnerJumpers){
runnerJumper.run();
runnerJumper.jump();
}
}
}
公共类TeamJumpers实现团队合作{
私人名单跳投者;
私人跑步运动员名单;
公共团队(名单跳投者,名单跳投者){
这个。跳线=跳线;
this.runnerJumpers=runnerJumpers;
}
@凌驾
公开竞逐(){
用于(跳线:跳线){
跳投;跳投;
}
用于(RunnerJumper RunnerJumper:runnerJumpers){
runnerJumper.run();
runnerJumper.jump();
}
}
}
不可能按你想象的方式去做
Java中的类型用于表示保证。对一段代码百分之百确定的事情。如果一段代码得到一只鸭
,则100%保证它也是一只鸟
和一只动物
但是你不能像“它不是一只鸭子
就是一只水桶
”这样表达关系。您需要同时扩展同一个超类型,并确保该类型仅由这两个超类型扩展;一般来说,它需要多个继承和密封类型
并且不能表示将值与类型混合的关系,比如“如果numberOfLegs==8
,那么类型就是Octopus
”。我不知道该如何调用此操作所需的aparatus,但我认为类型脚本中的结构类型可以表示此类约束。我认为duck类型是一个先决条件
回到Java:如果有一组对象可以包含Runner
s或RunnerJumper
s,那么在Java的类型系统中唯一可以保证的是所有对象都是Runner
s。任何泛型、继承等都不能改变这一点
您可以使用多种模式中的一种来实现您的业务目标:
将跳跃/运行行为重构为一个单独的类,两个类都使用一个perform
方法实现Action
。然后用一个方法创建一个接口:getActions
,例如,调用Player
。然后,您的团队
可以迭代玩家
s,获取每个玩家的操作,并在内部循环中调用他们的perform
方法。getAction
方法的实现甚至可以返回lambda的静态列表,这样您就可以从内部访问播放器的所有属性。此模式允许您保持可能操作的列表处于打开状态(引入新操作将不需要您重新编译或接触您的团队
类)
如果团队静态地知道可能的动作列表
,您可以使用访问者
模式-让团队调用玩家的访问
方法,玩家可以调用团队
的玩家跳跃(跳跃者j)
或玩家跳跃(跑步者r)
或者,您可以使用该语言的其他机制:反射和投射(这也将使可能的操作列表保持静态)。到目前为止您尝试了什么?请将您的团队类的当前实现添加到您的问题中。谢谢,但我们的想法是创建一个由跑步者或跳跃者组成的专属团队(跑步者团队可以包含Runner和RunnerJumper),在这种情况下,只需使用两个团队类即可。我已经更新了我的答案。我将跑步者定义为列表跑步者不是更容易吗?它将确保跑步者是RunnerJumper的跑步者,对于Competite
我可以迭代跑步者并让他们全部跑步
否,您不能使用列表
,因为IRunner是一个接口,所以不会编译。
public class Team<C extends Athlete> {}
interface Competitor {}
public class Team<C extends Competitor> {}
public interface Team {
public void compete();
}
public class TeamRunners implements Team {
private List<Runner> runners;
private List<RunnerJumper> runnerJumpers;
public Team(List<Runner> runners, List<RunnerJumper> runnerJumpers) {
this.runners = runners;
this.runnerJumpers = runnerJumpers;
}
@Override
public void compete() {
for (Runner runner : runners) {
runner.run();
}
for (RunnerJumper runnerJumper : runnerJumpers) {
runnerJumper.run();
runnerJumper.jump();
}
}
}
public class TeamJumpers implements Team {
private List<Jumper> jumpers;
private List<RunnerJumper> runnerJumpers;
public Team(List<Jumper> jumpers, List<RunnerJumper> runnerJumpers) {
this.jumpers = jumpers;
this.runnerJumpers = runnerJumpers;
}
@Override
public void compete() {
for (Jumper jumper : jumpers) {
jumper.jump();
}
for (RunnerJumper runnerJumper : runnerJumpers) {
runnerJumper.run();
runnerJumper.jump();
}
}
}