gpt4 book ai didi

java - 如何实现多功能类

转载 作者:行者123 更新时间:2023-12-01 22:43:06 25 4
gpt4 key购买 nike

所以,如果我有 4 个类,它们都是抽象父类(super class) Athlete 的派生类,并且每个类都有一个方法 race()。

类(class)包括运行、游泳、跨栏和铁人三项。

还有一个抽象的“Race”类,可扩展到 Race、HurdleRace 和 SwimRace。

现在,我希望运行者、游泳者和跨栏运动员都有一个 race() 方法,该方法根据运动类型返回一个随机数...所以运行 10-20 秒,跨栏 20-30 秒,30-游泳40多岁。

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

我认为使用接口(interface)会有所帮助,但我不知道它会如何?

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

谢谢!!

最佳答案

<强>1。选项1

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

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);
}

当您扩展类时,您指定运动员可以参加的确切比赛类型(因此方法签名将防止编译时出现错误):

class Runner extends Athlete<RunningRace> {
public abstract int participate(RunningRace race);
}

您可以将 TriAthlete 类定义为接受任何类型比赛的运动员子类型:

class TriAthlete extends Athlete<Race> {
public abstract int participate(Race race);
}

但是你会再次遇到与上面相同的问题(如果你想要一个知道如何参加两种类型的比赛的运动员子类型,你的 API 将如何防止其他程序员犯错误?)。

<强>2。选项2

我看到的另一种方法是为运动员编写多个界面:

public interface Athlete {}
public interface RunnerAthlete extends Athlete {
int participate(RunningRace race);
}
public interface SwimmerAthlete extends Athlete {
int participate(SwimmingRace 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) {}
}

您与最初的方法有些偏离。这种解决方案有优点也有缺点:你编写的代码较多,但接口(interface)很简单。此外,由于拥有太多的类/接口(interface),您可能会面临让新程序员更难学习“库”的风险。

<强>3。选项 3。

在企业应用程序中,在模型类中添加逻辑被认为是一种不好的做法(有争议 - 请参阅 http://en.wikipedia.org/wiki/Anemic_domain_model )。模型类(运动员、比赛)应仅包含描述实体所需的信息(例如,您需要知道比赛的长度和运动员的速度才能返回合理的结果)以及该字段的 getter/setter 。因此,像“int attend(Race r)”这样的方法正在耦合这两个类(运动员不仅知道 Race 类,而且还实现了其中的逻辑 - 生成随机结果)。

您可以拥有仅包含 getter 和 setter 的简单模型类,它们以与选项 2 中类似的方式扩展接口(interface),并拥有一个保存组织竞赛逻辑的“服务”类:

class CompetitionOrganizerService<A extend Athlete, R extends Race> {
public List<Result> organize(List<A> participants, R competition);
}

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

关于java - 如何实现多功能类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25820162/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com