Java类继承/接口实现原理

时间:2015-02-12 14:15:50

标签: java jsp spring-mvc inheritance interface

我不确定在特定情况下使用继承/接口实现。

在我简单的Spring MVC应用程序中,我有@Entity类TennisPlayer,它继承自抽象类Player(TennisPlayer添加了一些属性)。

我还有类TennisPlayerForm,它继承自抽象类PlayerForm(TennisPlayerForm再次添加一些属性)。

用户在.jsp页面填写关于网球运动员的表格,而TennisPlayerForm对象则用于表示填充值,然后在此对象的基础上创建TennisPlayer对象并保存到数据库中。

TennisPlayer对象的创建是TennisPlayerDbService类的责任。这个类是接口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)的具体实现需要特定类的实例时,尽管这些潜在的类具有共同的父类?

2 个答案:

答案 0 :(得分:1)

最后,我根据你的意见和答案解决了我的问题。

我在@Entity类播放器和网球播放器中删除了PlayerForm抽象类,TennisPlayerForm和混合的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();
    }
}

答案 1 :(得分:0)

通常,您的服务不需要知道您正在使用表单。您的表单纯粹是作为网页的模型 - 视图 - 控制器体系结构中的模型创建的。 (你的jsp是视图而你的控制器是c部分)

您是否还计划使用其他类型的玩家而不是TennisPlayer?如果不是这一切似乎都是过早的优化,你应该尽可能简单。