[英]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
toMovieDto
为UserMovie
? 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
. 这样,您不仅将返回所需的接口,还将返回与
toMovieDto
和toUserMovieDto
的返回类型相同类型的具体类。
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.