在各个子类初始化name

在父类Animal中定义了public String name;同时还有对应的getter和setter方法.
在子类Cat中有public String name = "猫",在测试类中创建子类实例cat.
使用cat.getName(),结果不是"猫",而是"null",为什么不行啊?
就是Animal有多个子类,我想在各个子类初始化name,要怎么实现?

引用 皆我百晓生 小程序回复内容作答:

在Java中,默认情况下,子类的成员变量会隐藏父类的同名成员变量。所以在子类Cat中,虽然也有一个名为name的成员变量,但它隐藏了父类Animal中的name成员变量。

当你创建子类实例cat并调用cat.getName()方法时,实际上是调用的父类Animal中的getName()方法。在该方法中,由于没有为name成员变量赋值,所以返回的是null。

要解决这个问题,你可以在子类Cat的构造方法中调用父类Animal的setter方法,为name成员变量赋值。例如:

public class Animal {
    private String name;
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getName() {
        return name;
    }
}

public class Cat extends Animal {
    public Cat() {
        setName("猫");
    }
}

public class Test {
    public static void main(String[] args) {
        Cat cat = new Cat();
        System.out.println(cat.getName()); // 输出:"猫"
    }
}

这样,在创建Cat实例时,会调用父类Animal的setName方法,将name成员变量赋值为"猫"。

【以下回答由 GPT 生成】

问题的根本原因是在子类中没有调用父类的构造函数,导致父类的name属性没有被正确初始化。正确的解决方案是在子类的构造函数中调用父类的构造函数来完成属性的初始化。

class Cat : public Animal {
public:
    Cat() : Animal() { // 在子类构造函数的初始化列表中调用父类的构造函数
        name = "猫";
    }
};

通过在子类的构造函数初始化列表中调用父类的构造函数,可以保证父类的属性在子类对象构造时被正确初始化。这样在调用子类的getName()方法时,能够得到正确的name属性值。

完整代码如下:

#include <iostream>
#include <string>

class Animal {
public:
    std::string name;

    Animal() {
        name = "动物";
    }

    std::string getName() {
        return name;
    }
};

class Cat : public Animal {
public:
    Cat() : Animal() { // 在子类构造函数的初始化列表中调用父类的构造函数
        name = "猫";
    }
};

int main() {
    Cat cat;
    std::string catName = cat.getName();
    std::cout << catName << std::endl; // 输出"猫"
    return 0;
}

输出结果为"猫",符合预期。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^