如何将重复的@SerializedName注解统一到基类,优化TmdbItem实现代码?
解决方案:统一公共字段的
@SerializedName注解 可以通过将TmdbItem从接口改为抽象类来实现公共字段注解的统一,避免在Movie和TVShow中重复定义。
核心原因
Kotlin接口中的属性默认是抽象的,无法为其添加@SerializedName这类运行时注解(注解会被忽略,因为接口不会生成对应的成员字段)。而抽象类允许定义带注解的成员属性,子类继承后可直接复用这些注解。
具体实现步骤
1. 重构TmdbItem为带@Parcelize的抽象类
将所有公共字段(包括poster_path、backdrop_path)连同对应的@SerializedName注解统一放在抽象类中:
@Parcelize abstract class TmdbItem : Parcelable { @SerializedName("id") abstract val id: Int @SerializedName("overview") abstract val overview: String? @SerializedName("release_date") abstract val releaseDate: String? @SerializedName("poster_path") abstract val posterPath: String? @SerializedName("backdrop_path") abstract val backdropPath: String? }
2. 让数据类继承抽象类并实现独有字段
Movie和TVShow只需覆盖抽象类的属性(无需重复写注解),并定义各自独有的字段:
@Parcelize data class Movie( override val id: Int, override val overview: String?, override val releaseDate: String?, override val posterPath: String?, override val backdropPath: String?, @SerializedName("title") val title: String?, @SerializedName("vote_average") val voteAverage: Double? ) : TmdbItem() @Parcelize data class TVShow( override val id: Int, override val overview: String?, override val releaseDate: String?, override val posterPath: String?, override val backdropPath: String?, @SerializedName("name") val name: String?, @SerializedName("first_air_date") val firstAirDate: String? ) : TmdbItem()
替代方案(构造函数传参式)
如果偏好父类构造函数传参的方式,也可以这样定义抽象类:
@Parcelize abstract class TmdbItem( @SerializedName("id") open val id: Int, @SerializedName("overview") open val overview: String?, @SerializedName("release_date") open val releaseDate: String?, @SerializedName("poster_path") open val posterPath: String?, @SerializedName("backdrop_path") open val backdropPath: String? ) : Parcelable
子类继承时只需传入父类参数并添加独有字段:
@Parcelize data class Movie( override val id: Int, override val overview: String?, override val releaseDate: String?, override val posterPath: String?, override val backdropPath: String?, @SerializedName("title") val title: String?, @SerializedName("vote_average") val voteAverage: Double? ) : TmdbItem(id, overview, releaseDate, posterPath, backdropPath)
内容的提问来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

