如何在Java子类中访问父类定义的ArrayList并正确重写方法?
问题描述
现有四个类(Student、Subject、HighSchool、Scientific),继承关系为:HighSchool 继承自 Student,Scientific 继承自 HighSchool。
在HighSchool类中定义了一个Subject类型的ArrayList(命名为subjects),并实现了一个计算平均分的方法,该方法运行正常:
public double calculateAverage() { if (this.subjects.size() <= 0) return 0; double sum = 0; for(int i = 0; i < this.subjects.size(); i++) { sum += this.subjects.get(i).getMark(); } return (sum / this.subjects.size()); }
现在想在Scientific类中重写该方法,但访问subjects ArrayList时出现问题——ArrayList始终为空(未添加subjects),简化后的子类代码如下:
public double calculateAverage() { if (this.getSubjects().size() <= 0) return 0; double sum = 0; else{ for (int i = 0; i < getSubjects().size(); i++) { sum += this.getSubjects().get(i).getMark(); } } // 原代码缺失return语句,保留原始内容 }
已尝试使用super关键字并修改修饰符,但问题仍未解决,不确定this.getSubjects()的使用方式是否正确,寻求可行的解决方法。
解决方案
1. 优先排查subjects的初始化与赋值逻辑
ArrayList为空的核心原因大概率不是访问方式错误,而是当前Scientific实例的subjects未被正确赋值:
- 确认是否给同一个Scientific实例添加科目,避免因创建多个实例导致计算时用的是无数据的实例;
- 检查HighSchool的构造函数是否初始化了
subjects(比如subjects = new ArrayList<>();),父类方法能正常运行说明父类已初始化,但要确保子类实例继承的变量完成初始化。
2. 正确访问subjects的方式
- 如果HighSchool中
subjects的修饰符是protected,子类可直接用this.subjects访问,和父类写法一致,无需额外调用getSubjects(); - 若使用
getSubjects(),需确保该方法返回的是当前实例的subjects变量,错误写法(返回新集合)会导致空列表:// 错误示例:不要返回新集合 protected List<Subject> getSubjects() { return new ArrayList<>(); } // 正确写法:返回当前实例的subjects protected List<Subject> getSubjects() { return this.subjects; }
3. 子类重写方法的正确示例
假设subjects为protected修饰,重写方法可参考:
@Override public double calculateAverage() { if (this.subjects.isEmpty()) { return 0; } double sum = 0; for (Subject subject : this.subjects) { sum += subject.getMark(); } // 若Scientific需特殊计算逻辑(如加权平均分),可在此修改 return sum / this.subjects.size(); }
若使用getSubjects(),确保方法正确后,写法如下:
@Override public double calculateAverage() { List<Subject> subjects = this.getSubjects(); if (subjects.isEmpty()) { return 0; } double sum = 0; for (Subject subject : subjects) { sum += subject.getMark(); } return sum / subjects.size(); }
4. 额外检查点
- 重写方法时添加
@Override注解,确保是正确覆盖父类方法,而非新建同名方法; - 检查子类是否重新定义了
subjects变量,若Scientific中存在private ArrayList<Subject> subjects;,会覆盖父类变量,导致父类添加的科目无法被子类访问。
内容的提问来源于stack exchange,提问作者Codere
相关产品推荐
相关产品推荐

