Javaclassinheritance/interface实现原理
Java class inheritance/interface implementation principle
我不确定在特定情况下使用继承/接口实现。
在我的简单 Spring MVC 应用程序中,我有 @Entity class TennisPlayer,它继承自抽象 class Player(TennisPlayer 添加了一些属性)。
另外我还有class TennisPlayerForm,它继承自abstract class PlayerForm(TennisPlayerForm 又增加了一些属性)。
用户在.jsp页面填写关于网球运动员的表格,TennisPlayerForm对象用于表示填写的值,然后在此对象的基础上创建TennisPlayer对象并保存到数据库中。
TennisPlayer 对象的创建由 class TennisPlayerDbService 负责。 class 是 PlayerService 接口的实现。
我有以下处理请求的@Controller:
@Controller
public class NewPlayerController {
@Resource(name="tennisPlayerService")
private PlayerService playerService;
//omitted RequestMethod.GET handler method
@RequestMapping(value = "/newplayer", method = RequestMethod.POST)
public String newplayer(Locale locale, @ModelAttribute("tennisPlayerForm") @Valid TennisPlayerForm tennisPlayerForm,
BindingResult result, RedirectAttributes redirectAttributes) {
playerService.createPlayer(tennisPlayerForm);
return "redirect:/allplayers";
}
}
我的部分源代码如下所示:
public interface PlayerService {
public void createPlayer(PlayerForm playerForm);
}
@Service(value="tennisPlayerService")
public class TennisPlayerDbService implements PlayerService {
private TennisPlayerDAO dao;
@Autowired
public void setDao(TennisPlayerDAO dao) {
this.dao = dao;
}
@Override
public void createPlayer(PlayerForm playerForm) {
TennisPlayerForm tennisPlayerForm = null;
if (playerForm instanceof TennisPlayerForm) {
tennisPlayerForm = (TennisPlayerForm) playerForm;
}
else {
throw new IllegalArgumentException("Must be of type TennisPlayerForm.");
}
TennisPlayer player = new TennisPlayer();
player.setName(tennisPlayerForm.getName());
player.setSurname(tennisPlayerForm.getSurname());
player.setAge(tennisPlayerForm.getAge());
player.setRacket(tennisPlayerForm.getRacket());
player.setRanking(tennisPlayerForm.getRanking());
player.setSponsor(tennisPlayerForm.getSponsor());
player.setCoach(tennisPlayerForm.getCoach());
player.setClub(tennisPlayerForm.getClub());
dao.saveAndFlush(player);
}
}
在这种情况下,当 PlayerService (TennisPlayerDbService) 的具体实现需要特定 class 的实例时,尽管这些潜在的 classes 具有共同的父级,但在这种情况下使用继承和接口实现是否合理?
通常您的服务不需要知道您正在使用表单。您的表单纯粹是为了成为您网页的模型-视图-控制器架构中的模型而创建的。 (您的 jsp 是视图,您的控制器是 c 部分)
您是否还打算使用 TennisPlayer
以外的其他类型的播放器?如果不是,这一切似乎都是过早的优化,您应该尽可能简单。
最后我根据您的评论和回答解决了我的问题。
我删除了 PlayerForm 摘要 class、TennisPlayerForm,并在 @Entity classes Player 和 Tennis Player 中混合了 javax.validation 和 javax.persistence 注释。
之前提到的代码现在看起来像这样:
@Controller
public class NewPlayerController {
@Resource(name="tennisPlayerService")
private PlayerService<TennisPlayer> playerService;
//omitted RequestMethod.GET handler method
@RequestMapping(value = "/newplayer", method = RequestMethod.POST)
public String newplayer(Locale locale, @ModelAttribute("tennisPlayer") @Valid TennisPlayer tennisPlayer,
BindingResult result, RedirectAttributes redirectAttributes) {
if(result.hasErrors()) {
return "newplayer";
}
playerService.createPlayer(tennisPlayer);
MessageUtil.flash(locale, redirectAttributes, "success", "signup.success");
return "redirect:/allplayers";
}
}
public interface PlayerService<T extends Player> {
public void createPlayer(T player);
public List<T> getAllPlayers();
}
@Service(value="tennisPlayerService")
public class TennisPlayerDbService implements PlayerService<TennisPlayer> {
private TennisPlayerDAO dao;
@Autowired
public void setDao(TennisPlayerDAO dao) {
this.dao = dao;
}
@Override
public void createPlayer(TennisPlayer player) {
dao.saveAndFlush(player);
}
@Override
public List<TennisPlayer> getAllPlayers() {
return dao.findAll();
}
}
我不确定在特定情况下使用继承/接口实现。
在我的简单 Spring MVC 应用程序中,我有 @Entity class TennisPlayer,它继承自抽象 class Player(TennisPlayer 添加了一些属性)。
另外我还有class TennisPlayerForm,它继承自abstract class PlayerForm(TennisPlayerForm 又增加了一些属性)。
用户在.jsp页面填写关于网球运动员的表格,TennisPlayerForm对象用于表示填写的值,然后在此对象的基础上创建TennisPlayer对象并保存到数据库中。
TennisPlayer 对象的创建由 class TennisPlayerDbService 负责。 class 是 PlayerService 接口的实现。
我有以下处理请求的@Controller:
@Controller
public class NewPlayerController {
@Resource(name="tennisPlayerService")
private PlayerService playerService;
//omitted RequestMethod.GET handler method
@RequestMapping(value = "/newplayer", method = RequestMethod.POST)
public String newplayer(Locale locale, @ModelAttribute("tennisPlayerForm") @Valid TennisPlayerForm tennisPlayerForm,
BindingResult result, RedirectAttributes redirectAttributes) {
playerService.createPlayer(tennisPlayerForm);
return "redirect:/allplayers";
}
}
我的部分源代码如下所示:
public interface PlayerService {
public void createPlayer(PlayerForm playerForm);
}
@Service(value="tennisPlayerService")
public class TennisPlayerDbService implements PlayerService {
private TennisPlayerDAO dao;
@Autowired
public void setDao(TennisPlayerDAO dao) {
this.dao = dao;
}
@Override
public void createPlayer(PlayerForm playerForm) {
TennisPlayerForm tennisPlayerForm = null;
if (playerForm instanceof TennisPlayerForm) {
tennisPlayerForm = (TennisPlayerForm) playerForm;
}
else {
throw new IllegalArgumentException("Must be of type TennisPlayerForm.");
}
TennisPlayer player = new TennisPlayer();
player.setName(tennisPlayerForm.getName());
player.setSurname(tennisPlayerForm.getSurname());
player.setAge(tennisPlayerForm.getAge());
player.setRacket(tennisPlayerForm.getRacket());
player.setRanking(tennisPlayerForm.getRanking());
player.setSponsor(tennisPlayerForm.getSponsor());
player.setCoach(tennisPlayerForm.getCoach());
player.setClub(tennisPlayerForm.getClub());
dao.saveAndFlush(player);
}
}
在这种情况下,当 PlayerService (TennisPlayerDbService) 的具体实现需要特定 class 的实例时,尽管这些潜在的 classes 具有共同的父级,但在这种情况下使用继承和接口实现是否合理?
通常您的服务不需要知道您正在使用表单。您的表单纯粹是为了成为您网页的模型-视图-控制器架构中的模型而创建的。 (您的 jsp 是视图,您的控制器是 c 部分)
您是否还打算使用 TennisPlayer
以外的其他类型的播放器?如果不是,这一切似乎都是过早的优化,您应该尽可能简单。
最后我根据您的评论和回答解决了我的问题。
我删除了 PlayerForm 摘要 class、TennisPlayerForm,并在 @Entity classes Player 和 Tennis Player 中混合了 javax.validation 和 javax.persistence 注释。
之前提到的代码现在看起来像这样:
@Controller
public class NewPlayerController {
@Resource(name="tennisPlayerService")
private PlayerService<TennisPlayer> playerService;
//omitted RequestMethod.GET handler method
@RequestMapping(value = "/newplayer", method = RequestMethod.POST)
public String newplayer(Locale locale, @ModelAttribute("tennisPlayer") @Valid TennisPlayer tennisPlayer,
BindingResult result, RedirectAttributes redirectAttributes) {
if(result.hasErrors()) {
return "newplayer";
}
playerService.createPlayer(tennisPlayer);
MessageUtil.flash(locale, redirectAttributes, "success", "signup.success");
return "redirect:/allplayers";
}
}
public interface PlayerService<T extends Player> {
public void createPlayer(T player);
public List<T> getAllPlayers();
}
@Service(value="tennisPlayerService")
public class TennisPlayerDbService implements PlayerService<TennisPlayer> {
private TennisPlayerDAO dao;
@Autowired
public void setDao(TennisPlayerDAO dao) {
this.dao = dao;
}
@Override
public void createPlayer(TennisPlayer player) {
dao.saveAndFlush(player);
}
@Override
public List<TennisPlayer> getAllPlayers() {
return dao.findAll();
}
}