这段代码不是很理解 具体代码 希望理解的人帮忙解释一下


#1
open class Father {
    var number: Int

    init {
        number = createNumber()
    }

    open fun createNumber(): Int {
        return 10
    }
}

class Son(private val n: Int) : Father() {

    override fun createNumber(): Int {
        return n
    }
}

abstract class Base {

    val code: Int = calculate()

    abstract fun calculate(): Int
}

class Derived(private val x: Int) : Base() {

    override fun calculate(): Int = x

}

fun main() {
    println(Son(42).number)
    println(Derived(42).code)
}

0
0

Process finished with exit code 0

//打印都是0  第一个是自己写的  下面的这个是 as警告中所携带的 示例代码

按照理解 son集成了father的number变量 初始化的son并且调用他的number时 先实例化father 并且实例化number 调用了createNumber返回了10 那么number的值 时10 son集成过来了 打印却是0 不是10 不知道为什么

下面这个 例子呢 按照我的理解 是这样的 Derived调用构造方法 传递了42给x 类中重写了calculate 把传递进来的42返回了 然后调用Derived的code时 code的值 时调用了calculate方法 应该是等于calculate返回的42 才对 为啥是0呢?


#2

如果先学习 Java 再学习 Kotlin 估计就不会有这个问题,把你上面的代码翻译成等价的 Java 大概是这样子的(省略了访问修饰符等细节):

class Father {
    int number;

    Father() {
        this.number = createNumber();
    }

    int createNumber() {
        return 10;
    }
}

class Son extends Father {
    int n;

    Son(int n) {
        this.n = n;
    }

    @Override
    int createNumber() {
        return n;
    }
}

public class Test {

    public static void main(String[] args) {
        System.out.println(new Son(42).number);
    }
}

#3

这个问题与构造方法的调用顺序有关,当实例化 Son 时,会先调用父类 Father 的构造方法,再调用子类的构造方法

在调用父类构造方法的时候,我们使用 createNumber 方法获取一个数字,但是这个方法是虚方法,会被动态分派到子类的 createNumber,因此实际调用的应该是子类的方法

问题就出在这里,这个时候对象还没有构造完成,子类的构造方法实际上还没有被调用,因此 n 实际是还是初始的 0 值,这就是为什么你的输出结果是 0 的原因


#4

这是 Java 的一个常见的坑,一般来说,我们的最佳实践是不要在构造方法中调用任何虚方法,以避免访问到未构造完成的对象,产生意料之外的结果,这个最佳实践尤其在并发编程中会显得更为重要


#5

在调用父类构造方法的时候,我们使用 createNumber 方法获取一个数字,但是这个方法是虚方法 这个方法为什么叫虚方法呢?怎么定义的呢 我不太懂 虚方法的意思


#6

却是如此 我调试的时候 init调用了createNumber 其实是调用的子类的 但是我一直不明白 方法明明是在父类的 却调用的子类的createNumber 而且就算是我加了this.createNumber 他还是调用的子类的createNumber 并且this是 子类的对象


#7

createNumber 方法 为什么会被动态分配到 子类son中呢


#8

虚方法就是 open 方法


京ICP备16022265号-2 Kotlin China 2017 - 2018