有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Kotlin中的java简单继承示例

在Java中,我有两个类:

public class Base {
    protected Long id;
    // getter setter
}
public User extends Base {
    private String name;
    private Integer age;
    public User(Long id) { this.id = id; }
    // getter setter
}

我在Kotlin中创建了这两个类:

open class Base(var id: Long? = null)
class User(
        var id: Long? = null,
        var name: String? = null,
        var age: Int? = null
) : Base()

现在在Java中,我只想用'id'参数调用User()构造函数:

new User(5);

这对我来说似乎是错误的,因为通过这样做,我在用户类中重新声明了“id”字段

如何在Kotlin中设置基类的id字段(就像我在Java中使用“this.id=id;”时所做的那样)


共 (3) 个答案

  1. # 1 楼答案

    首先,Kotlin代码将无法编译,因为会出现以下错误:Error:'id' hides member of supertype 'Base' and needs 'override' modifier

    基本上,编译器也会抱怨您在{}中从{}重新声明了{}

    如果要重新声明,需要首先在Base中生成id{a1},然后在User中,在重新声明id时,需要使用override关键字。(另见this

    此外,为了让Kotlin编译器生成User构造函数的重载,需要用@JvmOverloads注释主构造函数。如果没有@JVM重载,您将无法在Java中使用User(id)构造函数(仅id作为参数),并且必须指定所有3个参数

    因此,您的代码将变成:

    open class Base(open var id: Long? = null)
    
    class User @JvmOverloads constructor(override var id: Long? = null,
                                         var name: String? = null,
                                         var age: Int? = null
    ) : Base(id)
    

    现在,如果您不想在User中重新声明id,您可以简单地不在它前面使用var,而是在调用它的构造函数时直接将它传递给Base。所以基本上是这样的:

    open class Base(var id: Long? = null)
    
    class User @JvmOverloads constructor(id: Long? = null,
                                         var name: String? = null,
                                         var age: Int? = null
    ) : Base(id)
    
  2. # 2 楼答案

    首先,当您尝试运行代码时,代码将给出错误:'id' hides member of supertype 'Base' and needs 'override' modifier
    这是因为当kotlin编译器看到var id: Long? = null时,它将尝试创建一个名为id且类型为Long?的变量。但由于继承,它的作用域中可能已经有了id变量
    因此,编译器将投诉您访问或创建变量,从而出现上述错误

    现在回答你的问题:How can I set the id field of the base class in Kotlin
    您可以通过以下方式实现:

    open class Base(var id: Long?=null)
    class User(
            id: Long?=null,
            var name: String? = null,
            var age: Int? = null
    ) : Base(id)
    

    在上面的代码中,我所做的是重写了子类构造函数User中的id变量。因此,这个id变量可以将任何Long类型的值(我们将在调用User类构造函数时传递)或null作为默认值
    在此之后,我刚刚通过Base(id)将这个新值传递给了Base类,这与在java中执行this.id = id相同

    希望这个答案有帮助

  3. # 3 楼答案

    我相信这只是将ID传递给超类的构造函数的问题

    open class Base(var id: Long? = null)
    class User(
        var id: Long? = null,
        var name: String? = null,
        var age: Int? = null
    ) : Base(id)