使用外部类的val/方法作为嵌套数据类声明中的默认值

问题描述 投票:0回答:1

考虑以下玩具示例:

class A{
    val a=1

    fun hello() =println("hello")

    init {
        println(a)
        println(this::hello)
    }

    data class B(val b: Int = a, val func: () -> Unit = this::hello)
}

这不会编译,会显示错误:

Unresolved reference: a
'this' is not defined in this context
。这让我很困惑,因为它们在前面的
init
中可用。

为什么父级的 vals/vars/methods 在数据类声明中不可访问,即使它是嵌套的?

尽管有大量与“*kotlin*nested*data*”匹配的问题,但我找不到答案。

kotlin nested initialization
1个回答
0
投票

可以在另一个类中声明两种不同类型的类:

  • 嵌套类:这些只是简单的类定义,与封闭类没有任何联系,除了它们必须使用外部类显式限定:

    fun someUnrelatedFunction() {
        val b = A.B()
    }
    

    这就是你所拥有的:两个独立的类,两个独立的实例,两个独立的

    this
    对象。因此你无法访问外部类的
    this

  • 内部类:另一方面,内部类只能与外部类的实例一起存在。这意味着它们不能被实例化。通常内部类的对象是由外部类创建的。在这种情况下,外部类的实例可用并且可以由内部类访问: class A { val a = 1 fun hello() = println("hello") init { println(a) println(this::hello) } inner class B(val b: Int = a, val func: () -> Unit = this::hello) }

    现在可以编译了,因为 
    B

    被定义为

    inner class
    。请注意,数据类不能是内部类,所以我删除了
    data
    虽然现在可以使用,但以下内容不再有效:

    fun someUnrelatedFunction() { val b = A.B() }

    编译器抱怨此错误消息:

    内部类B的构造函数只能通过包含类的接收者来调用

    您可以在类
    A

    中创建以下属性:

    val b = B()
    

    
    
  • 在文档中阅读有关
嵌套类和内部类

的更多信息。 作为结束语,因为您在问题中谈到了

父类

:父类仅存在于一个类扩展另一个类的继承层次结构中。但这完全不相关,并且与您的示例中的代码无关。您的代码是关于 outerinner 类,而不是关于父类和子类。

© www.soinside.com 2019 - 2024. All rights reserved.