Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何实现多功能类_Java_Oop - Fatal编程技术网

Java 如何实现多功能类

Java 如何实现多功能类,java,oop,Java,Oop,如果我有4个类,它们都是抽象超类Athletor的派生类,每个类都有一个方法race() 课程包括跑步、游泳、跨栏和铁人三项 还有一个抽象的“Race”类,它扩展到Race、跨栏跑和泳道 现在,我想让跑步者、游泳者和跨栏运动员都有一个race()方法,该方法根据运动项目返回一个随机数…所以跑步10-20秒,跨栏20-30秒,游泳30-40秒 现在铁人三项运动员可以参加三种比赛中的任何一种,但我显然希望他们的随机返回值取决于比赛类型。实现这一点的最佳方式是什么 我认为使用界面会有帮助,但我不知道这

如果我有4个类,它们都是抽象超类Athletor的派生类,每个类都有一个方法race()

课程包括跑步、游泳、跨栏和铁人三项

还有一个抽象的“Race”类,它扩展到Race、跨栏跑和泳道

现在,我想让跑步者、游泳者和跨栏运动员都有一个race()方法,该方法根据运动项目返回一个随机数…所以跑步10-20秒,跨栏20-30秒,游泳30-40秒

现在铁人三项运动员可以参加三种比赛中的任何一种,但我显然希望他们的随机返回值取决于比赛类型。实现这一点的最佳方式是什么

我认为使用界面会有帮助,但我不知道这会有什么效果

我可以附加代码,但我意识到我只是附加了很多,问题实际上是概念性的——更多的是关于我对面向对象编程的理解


谢谢

由于您也在为比赛使用特定的类,因此似乎最好为
运动员
的每个子类指定其自己的
比赛
对象作为实例变量——因此
跑步者
比赛
,游泳者的
泳道
,等等,三项铁人三项赛的所有三场比赛。然后让每个
Race
子类都有一个生成比赛时间的方法。然后,每个
运动员
子类可以询问自己的
种族
对象的时间,而
铁人三项
可以询问其三个对象中的每一个对象的时间。

因为您也在为比赛使用特定的类,似乎最好将
atternate
的每个子类都作为一个实例变量赋予它自己的
Race
对象——因此
Race
对于
Runner
,a
SwimRace
对于
swimer
,等等,这三个比赛都是针对
TriAthlete
。然后让每个
Race
子类都有一个生成比赛时间的方法。然后,每个
运动员
子类可以询问自己的
种族
对象的时间,而
铁人三项
可以询问其三个对象中的每一个对象的时间。

因为您也在为比赛使用特定的类,似乎最好将
atternate
的每个子类都作为一个实例变量赋予它自己的
Race
对象——因此
Race
对于
Runner
,a
SwimRace
对于
swimer
,等等,这三个比赛都是针对
TriAthlete
。然后让每个
Race
子类都有一个生成比赛时间的方法。然后,每个
运动员
子类可以询问自己的
种族
对象的时间,而
铁人三项
可以询问其三个对象中的每一个对象的时间。

因为您也在为比赛使用特定的类,似乎最好将
atternate
的每个子类都作为一个实例变量赋予它自己的
Race
对象——因此
Race
对于
Runner
,a
SwimRace
对于
swimer
,等等,这三个比赛都是针对
TriAthlete
。然后让每个
Race
子类都有一个生成比赛时间的方法。然后每个
运动员
子类可以询问自己的
比赛
对象的时间,而
铁人三项运动员
可以询问三个对象中的每一个对象的时间。

怎么样:

abstract class Race {
    int minScore, maxScore;
    // set those values in the constructor
    // add getter methods (int getMinScore, int getMaxScore)
}

class SwimRace {
    SwimRace() {
        super(30, 40);
    }
}

class Athlete {
    int race(Race race) {
        // maybe first validate that this athlete can compete in this type of race?
        int min = race.getMinScore(), max = race.getMaxScore();
        return min + (int)(Math.random() * (max-min));
    }
}
那么:

abstract class Race {
    int minScore, maxScore;
    // set those values in the constructor
    // add getter methods (int getMinScore, int getMaxScore)
}

class SwimRace {
    SwimRace() {
        super(30, 40);
    }
}

class Athlete {
    int race(Race race) {
        // maybe first validate that this athlete can compete in this type of race?
        int min = race.getMinScore(), max = race.getMaxScore();
        return min + (int)(Math.random() * (max-min));
    }
}
那么:

abstract class Race {
    int minScore, maxScore;
    // set those values in the constructor
    // add getter methods (int getMinScore, int getMaxScore)
}

class SwimRace {
    SwimRace() {
        super(30, 40);
    }
}

class Athlete {
    int race(Race race) {
        // maybe first validate that this athlete can compete in this type of race?
        int min = race.getMinScore(), max = race.getMaxScore();
        return min + (int)(Math.random() * (max-min));
    }
}
那么:

abstract class Race {
    int minScore, maxScore;
    // set those values in the constructor
    // add getter methods (int getMinScore, int getMaxScore)
}

class SwimRace {
    SwimRace() {
        super(30, 40);
    }
}

class Athlete {
    int race(Race race) {
        // maybe first validate that this athlete can compete in this type of race?
        int min = race.getMinScore(), max = race.getMaxScore();
        return min + (int)(Math.random() * (max-min));
    }
}

1。选项1

您可以尝试将“真实”对象建模为Java类。 一个真正的运动员通常参加一场比赛->运动员课程应该掌握与运动员相关的信息(例如,他在好天气的速度),并且应该知道参加比赛(有一种方法允许)。 比赛具有某些属性(例如,长度;完成时间应随此属性而变化)->race类应保存与比赛相关的信息

abstract class Athlete {
    public abstract int participate(Race raceToParticipateInto);
}
但是,正如您指定的,您希望有多种类型的比赛和运动员,因此使用上面的签名将编写非常糟糕的API。您应该专注于编写不允许客户端出错的API。您不想让其他使用您的类的程序员做出如下行为:

Runner runner = new Runner();
SwimRace swimmingRace = new SwimRace();
runner.participate(swimmingRace); -> this should be a compilation error.
为了解决这个问题,您可以使用泛型

abstract class Athlete<T extends Race> {
    public abstract int participate(T race);
}
并为它们提供了如下实现:

public class RunnerAthleteImpl implements RunnerAthlete {
    int participate(RunningRace race) {}
}

public class TriAthleteImpl implements RunnerAthlete, SwimmerAthlete, HurdlerAthlete {
    int participate(RunningRace race) {}
    int participate(SwimmingRace race) {}
    int participate(HurdleRace race) {}
}
你偏离了最初的方法。这种解决方案有优点也有缺点:您可以编写更多的代码,但接口很简单。另外,由于类/接口太多,您可能会使新程序员更难学习您的“库”

3。选项3。

在企业应用程序中,在模型类中添加逻辑被认为是一种不好的做法(可论证-请参阅)。模型类(运动员、比赛)应仅包含描述实体所需的信息(例如,为了返回合理的结果,您需要知道比赛的长度和运动员的速度)以及该字段的获取者/设定者。 因此,像“int-particiate(Race r)”这样的方法耦合了这两个类(运动员不仅知道Race类,而且在其中实现了逻辑-生成随机结果)

您可以有一个简单的模型类,其中只包含getter和setter,它们以与选项2中类似的方式扩展接口,并且有一个“service”类,它包含组织竞争的逻辑:

class CompetitionOrganizerService<A extend Athlete, R extends Race> {
    public List<Result> organize(List<A> participants, R competition);
}
班级竞争组织服务{
公开名单组织(名单参与者、R竞赛);
}

其中Result可以是一个类,该类包含运动员和代表该运动员结果的int值之间的配对。

1。选项1

您可以尝试将“真实”对象建模为Java类。 一个真正的运动员通常参加一场比赛->运动员课程应该掌握与该运动员相关的信息(例如他在比赛中的速度)