kotlin和java中遇到的问题(以前没有关注过的)

先看一段代码,猜猜结果是什么。

public class People2 {
    String name;

    public People2(String name) {
        this.name = name;
    }

    void test1() {
        System.out.println(this.name);
    }

    public static void main(String[] args) {
        // 是输出zyt还是People2
        // 换为super(name)就没问题了
        new Student2("zyt").test1();
        
    }

}

class Student2 extends People2 {

    String name;

    public Student2(String name) {
        super("People2");
        this.name = name;
    }
}

答案肯定是People2.

以前没有注意到这个问题哦,我是在kotlin语法中注意到这个问题,然后用JAVA试了一下也一样。kotlin代码如下

open class People(
    private val name: String
) {
    constructor() : this("People")

    fun funOfPeople(people: People) {
        println(people.javaClass) // 这里并没有问题
        // 当传入的参数是People的子类时,如果子类的属性和People的属性一样
        // 也不会调用子类的属性,除非子类覆盖People中名字相同的属性
        println(people.name)
    }

    fun fun2OfPeople() {
        // 这里也会出现同样的问题
        // 子类实例调用父类方法的,虽然this的类型是子类型
        // 但是当属性名子一样时,还是会调用父类的属性

        // 原因:因为在kotlin中类的属性是final的,子类不可以覆盖,
        // 那么我们在调用this.name时,肯定就是引用的父类中的属性,
        // 调用的是主构造器中的属性值
        // 解决方法和上面一样
        println(this.name)
    }
}

class Worker(
     val name: String
) : People()


fun main() {
    val worker1 = Worker("zyt")
    val people = People("shx")
    people.funOfPeople(worker1) // 为什么不是zyt
}

解决:

open class People(
    // 这里改为open,因为kotlin属性默认为final(子类不可覆盖)
    open val name: String
) {
    constructor() : this("People")

    fun funOfPeople(people: People) {
        println(people.javaClass)
        println(people.name)
    }

    fun fun2OfPeople() {
        println(this.name)
    }
}

class Worker(
    // 当子类属性名字一样时,需要添加override关键字
    override val name: String
) : People()

kotlin和java中遇到的问题(以前没有关注过的)

上一篇:Springboot2-@Transactional 事务不生效


下一篇:[题解]剑指 Offer 25. 合并两个排序的链表(C++)