【问题标题】:Declaring same property in Child class as in Parent在 Child 类中声明与 Parent 相同的属性
【发布时间】:2017-12-30 10:08:05
【问题描述】:

我最近关注了 Kotlin,并且有 Java 方面的经验。在 Java 中,我们可以声明与父字段同名的字段。当我在Kotlin 中做同样的事情时,它会给出错误name hides member of Super type User。我在这里错过了什么?

科特林

open class User(protected var name: String)

class TwitterUser(var name: String) : User(name)

Java 的相同概念

public class A {
    protected String name;
}

public class B extends A {
    String name;
}

【问题讨论】:

  • 技术上这样做是 Java also 隐藏了超类型的成员,Java 的编译器在发生这种情况时不会出错......但它可能会抛出警告在你。
  • Unlike Java,Kotlin 需要对可覆盖成员和覆盖进行显式注释。

标签: java kotlin


【解决方案1】:

问题是,您隐藏了原始属性的实现。但无论如何都有一种可能性:

open class User(protected open var name: String)

class TwitterUser(override var name: String) : User(name)

你只需要考虑,这主要改变了属性的实现。您将无法单独访问User.nameTwitterUser.name。还是一样的。

【讨论】:

  • 通过覆盖它说 name 属性在 User 类中是最终的
  • 哦,对了。您还需要打开name
【解决方案2】:

改成这样,

open class ClassParent(name: String) {

}

class ClassChild(name: String) : ClassParent(name) {

}

你可以使用初始化块,check details

【讨论】:

  • 我知道它会像这样工作。但是为什么上面的代码会报错呢?
  • 它不会覆盖父类的成员,您需要覆盖,因为您正在扩展父类,因此它会显示此错误
  • @mallaudin 最初的错误是因为数据类在其主要构造函数中不能有除 val 或 var 属性之外的参数。删除 data 关键字会解除此限制。
【解决方案3】:

如果您的超类已经拥有name 属性,那么任何子类也会自动拥有它。你为什么要在那个孩子身上再次定义它?最好将其简单地定义为构造函数的参数,而不是使其成为另一个属性:

open class User(protected var name: String)
//name is not a val/val! simply passed to the constructor as an argument
class TwitterUser(name: String) : User(name)

否则,如果您确实需要覆盖该属性,请使其在父级中打开并在子级中覆盖:

open class User(protected open var name: String)
class TwitterUser(override var name: String) : User(name) 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-27
    相关资源
    最近更新 更多