暴露属性和 Kotlin 数据类的接口

Posted

技术标签:

【中文标题】暴露属性和 Kotlin 数据类的接口【英文标题】:Interfaces exposing properties and Kotlin data classes 【发布时间】:2019-12-14 11:48:28 【问题描述】:

我在 Kotlin 中有一个数据类:

data class Image (val name: String, val url: URL) 

我想通过 REST(Spring Boot,JPA)提供这些图像的列表,但我只想提供某些属性(在此示例中只是名称,而不是 URL)。根据我的阅读,我需要使用投影 - 定义一个只包含“getName”函数的接口:

interface HasName 
  fun getName () : String

..然后设置数据类来实现这一点,并让 RestController 服务于 HasNames 而不是图像:

@GetMapping("/images")
fun getImages () : List <HasName> 
  return imageService.getImages()

(或者这就是我在 Java 中所做的)。

但是,如果我在 Kotlin 中这样做:

data class Image (val name: String, val url: URL) : HasName   

我收到一个错误:

意外覆盖:以下声明具有相同的 JVM 签名 (getUrl()Ljava/net/URL;):

public final fun &lt;get-url&gt;():在 com.figmentsignage.server.data.campaign.Image 中定义的 URL public abstract fun getUrl():在 com.figmentsignage.server.data.campaign.Image 中定义的 URL

有没有简单的方法解决这个问题?我可以给该方法一个不同的名称并在 Image 类中重新定义它,但这有点乱。或者我可以在界面中定义“名称”变量并在图像中覆盖它,再次混乱。理想情况下,我希望尽可能少地更改 Image 类。

【问题讨论】:

【参考方案1】:

这是我在 kotlin 中定义这些的方式,只需使用 name 属性(不需要 getName() 方法)并确保使用 override 关键字:

interface HasName 
   val name: String


data class Image(override val name: String, val url: URL): HasName

【讨论】:

我认为你是对的。我只是不想对 Image 类进行更改。如果 Image 实现了两个都声明“名称”的接口,这仍然有效吗? 应该可以正常工作,只要它们都声明具有相同类型的名称

以上是关于暴露属性和 Kotlin 数据类的接口的主要内容,如果未能解决你的问题,请参考以下文章

kotlin抽象类密封类接口

转向Kotlin——类和接口

Kotlin学习之路:继承

Kotlin——最详细的数据类密封类详解

(类对象和接口)

Kotlin类的初始化 ① ( 成员属性 | Kotlin 自动为成员字段生成 getter 和 setter 方法 | 手动设置成员的 getter 和 setter 方法 | 计算属性 )