简体   繁体   English

该方法返回具有子类字段的超类对象

[英]The method returns a superclass object with subclass fields

I have a Movie object in the program 我的程序中有一个Movie对象

public class Movie extends BaseDTO {
      ...
      public static class Builder<T extends Builder> extends BaseDTO.Builder<T> { ... }
}

from this object inherits UserMovie 从此对象继承UserMovie

public class UserMovie extends Movie {
     //there are two additional fields
     private final Integer yourRating;
     private final boolean favorited;

     public static class Builder extends Movie.Builder<Builder> { ... }
}

In some part of the code I want to convert entities to DTO objects. 在代码的某些部分中,我想将实体转换为DTO对象。 I have two methods. 我有两种方法。 One to convert entities into Movie DTO 一种将实体转换为Movie DTO的方法

static Movie toMovieDto(final MovieEntity movieEntity) {
    return ((Movie.Builder) initMovieDto(movieEntity)).build();
}

the second method to convert to UserMovie DTO 转换为UserMovie DTO的第二种方法

static UserMovie toUserMovieDto(final MovieEntity movieEntity, final UserEntity userEntity) {
    final UserMovie.Builder builder = initMovieDto(movieEntity);

   builder.withYourRating(...);
   builder.withFavorited(userEntity.getFavoritesMovies().contains(movieEntity));

    return builder.build();
}

both methods use a common method to initialize data in the Builder pattern 两种方法都使用通用方法来初始化Builder模式中的数据

private static UserMovie.Builder initMovieDto(final MovieEntity movieEntity) {
    final UserMovie.Builder builder = new UserMovie.Builder(
            movieEntity.getTitle(),
            movieEntity.getType()
    )
            .withId(movieEntity.getId().toString());

    builder.withRating(...);
    ...
    return builder;
}

It turns out that the toMovieDto method returns the UserMovie object. 事实证明, toMovieDto方法返回UserMovie对象。 Why is this happening? 为什么会这样呢? I do not want private fields for UserMovie to be returned in Movie . 我不希望在Movie返回UserMovie私有字段。 How to fix it? 如何解决?

Are you worried that someone might cast the Movie returned from toMovieDto into UserMovie ? 您是否担心有人会将从toMovieDto返回的Movie toMovieDtoUserMovie I wouldn't worry about that much - this requires explicit casting. 我不必担心那么多-这需要显式转换。 (Compare it how methods in eg Collections class are defined, or in any Collection implementations). (比较如何定义Collections类或任何Collection实现中的方法)。

If you are really worried about security (and only in this case) you need to create another initMovieDto method, that user builder from Movie and not from UserMovie like currently. 如果您真的担心安全性(并且仅在这种情况下),则需要创建另一个initMovieDto方法,该方法是从Movie而不是像目前那样从UserMovie

So something like this: 所以像这样:

private static Movie.Builder initMovieDto(final MovieEntity movieEntity) {
    final Movie.Builder builder = new Movie.Builder(
            movieEntity.getTitle(),
            movieEntity.getType()
    )
            .withId(movieEntity.getId().toString());
    ...
    return builder;
}

static Movie toMovieDto(final MovieEntity movieEntity) {
    return ((Movie.Builder) initMovieDto(movieEntity)).build();
}

and separate for UserMovie: 并分别用于UserMovie:

private static UserMovie.Builder initUserMovieDto(final MovieEntity movieEntity) {
    final UserMovie.Builder builder = new UserMovie.Builder(
            movieEntity.getTitle(),
            movieEntity.getType()
    )
            .withId(movieEntity.getId().toString());

    builder.withRating(...);
    ...
    return builder;
}

static UserMovie toUserMovieDto(final MovieEntity movieEntity, final UserEntity userEntity) {
    final UserMovie.Builder builder = initUserMovieDto(movieEntity);

   builder.withYourRating(...);
   builder.withFavorited(userEntity.getFavoritesMovies().contains(movieEntity));

    return builder.build();
}

This way you will return not only the interface like you want but also concrete class of the same type as the return type in toMovieDto and toUserMovieDto . 这样,您不仅将返回所需的接口,还将返回与toMovieDtotoUserMovieDto的返回类型相同类型的具体类。

Another option would be to define UserMovie builder such that one of it's options would accept a Movie builder. 另一种选择是定义UserMovie构建器,以便其中一个选项可以接受“电影”构建器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM