Java - Getter方法返回null

3
我正在为课程进行抽象超类练习,并且我卡住了,不知道为什么我的getter方法返回null。根据我的教师演示,子类中的setter方法被重写,而getter方法应该是在超类中定义的final方法。当我将getter方法移到子类中时,它们能够工作,因此我猜想这可能与它们位于不同类中有关,但由于我是面向对象编程的新手,我不知道是否正确以及如何纠正错误。
抽象超类:
public abstract class ProgrammingCourse {

    private double credits;
    private  String courseName;

    public final double getCredits() {
        return credits;
    }

    public abstract void setCredits(double credits);

    public final String getCourseName() {
        return courseName;
    }

    public abstract void setCourseName(String courseName);

样例子类:

  public class AdvancedJavaCourse extends ProgrammingCourse {

    private double credits;
    private String courseName;

    @Override
    public void setCourseName(String courseName) {
        if (courseName == null || courseName.length() == 0) {
            JOptionPane.showMessageDialog(null,
                    "Error: courseName cannot be null or empty");
            System.exit(0);
        }
        this.courseName = courseName;
    }

    @Override
    public void setCredits(double credits) {
        this.credits = credits;
    }

我如何尝试在我的主程序中处理这个问题:

     ProgrammingCourse[] courses = {new AdvancedJavaCourse(), 
     new IntroJavaCourse(), new IntroToProgrammingCourse()};

    courses[0].setCourseName("adv Java");
    courses[1].setCourseName("Intro Java");
    courses[2].setCourseName("Intro Programming");
    for (ProgrammingCourse pc : courses) {
        System.out.println(pc.getCourseName());
    }

    AdvancedJavaCourse advJava = new AdvancedJavaCourse();
    advJava.setCourseName("Advanced Java");

    System.out.println(advJava.getCourseName());

1
你为什么要复制类变量?这会产生“遮蔽”效应。 - PM 77-1
构造函数在哪里?你没有初始化超类属性(也没有子类属性)。试着这么做,问题就会解决。 - Jessica
我也曾经对重复变量感到困惑,但这正是我的老师在课堂上演示的代码,所以...... - TeamNormal
至于构造函数,我确实有它们,但值仍然为空,所以我将它们删除了。 - TeamNormal
2个回答

5

你的代码有一些问题。从AdvancedJavaCourse开始,你应该删除creditscourseName字段。这些字段可以从ProgrammingCourse中访问。

现在,每个字段只有一个声明,你应该在ProgrammingCourse中将这些字段标记为protected,或者创建一些getter/setter,以便你可以从AdvancedJavaCourse中更改它们的值。


1

在超类和子类中,必须避免声明具有相同名称的字段。

这就是所谓的变量/字段shadowing。即使语言允许这样做,也应该避免。

这里发生的情况是,AdcanceJavaCourse 的实例总共有4个字段,即两对 creditcourseName,一对是在 ProgrammingCourse 中声明的,另一对是在 AdvanceJavaCourse 中声明的。

ProgrammingCourse 中的代码将读取和写入在该类中声明的变量,而 AdvanceJavaCourse 中的代码将访问在该类中声明的字段。

可能你想要做的是删除 AdvanceJavaCourse 中的字段声明,并将 ProgrammingCourse 中的字段声明为 protected

另一种可能性是在 ProgramingCourse 中将这些字段声明为私有的,在 ProgramingCourse 中给出一个简单的 setter 方法:

  public void setField(Type value) {
     field = value;
  }

任何子类中的专用重写都可以通过使用带有 super. 前缀的父级 setter 和 getter 访问私有字段:
@Override 
public void setField(Type value) {
    ...
    super.setField(processedValue);
    ...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接