继承抽象类Employee时,子类参数无法传递至super()构造函数问题
解决子类调用super()构造函数后属性为null的问题
嘿,我明白你现在遇到的麻烦了——三个继承自Employee抽象类的子类,只有一个能把参数正确传给父类构造函数,另外两个实例化后父类的属性全是null。结合你给出的抽象类代码,我来帮你梳理几个最可能踩的坑,以及对应的解决办法:
最常见的问题排查点
1. 子类构造函数漏写或错误调用super()
首先,你的Employee类只有带参构造函数,没有无参构造。这意味着所有子类的构造函数必须显式调用super(fName, lName, SSN),否则编译器会尝试自动插入无参的super(),而父类没有这个构造,要么编译报错,要么(如果你偷偷加了无参构造但没赋值)导致父类属性为null。
比如这种错误写法:
public class SalariedEmployee extends Employee { private double salary; // 错误:漏写了super调用,或者传错了参数 public SalariedEmployee(String fName, String lName, String ssn, double salary) { this.salary = salary; // 这里没写super(fName, lName, ssn); } }
还有一种更隐蔽的错误:传递的参数名拼写错误,比如把构造函数的局部变量ssn写成了父类的属性名SSN(大小写敏感),导致传了一个未定义的变量。
2. 父类构造函数的赋值逻辑写错了
你给出的父类代码里写了this.SSN =...,这里很容易踩的坑是把参数和属性的赋值搞反了,或者属性名拼写错误。比如:
// 父类错误示例 public Employee(String fName, String lName, String SSN) { SSN = SSN; // 这是把参数赋值给自己,根本没给类的属性赋值! // 或者写成this.fName = fName; 但父类的属性是firstName,不是fName }
正确的写法应该是this.firstName = fName;,确保类的属性被正确赋值。
3. 子类构造函数错误传递了未初始化的属性
有些开发者会不小心把子类的属性(而不是构造函数的参数)传给super(),比如:
public class CommissionEmployee extends Employee { private double commissionRate; // 注意这里子类的参数名和父类属性名一样 private String firstName; // 错误:把子类自己的firstName传给super,但此时这个属性还没初始化,是null public CommissionEmployee(String firstName, String lastName, String SSN, double rate) { super(this.firstName, lastName, SSN); this.commissionRate = rate; } }
正确的做法是直接传递构造函数的参数:super(firstName, lastName, SSN);
正确的代码参考
我给你写一套可以直接对照的正确代码:
抽象类Employee
public abstract class Employee { private String firstName; private String lastName; private String SSN; // 父类带参构造,确保每个属性都正确赋值 public Employee(String fName, String lName, String SSN) { this.firstName = fName; this.lastName = lName; this.SSN = SSN; } // 加几个get方法方便测试属性是否正确 public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public String getSSN() { return SSN; } }
正确的子类示例(HourlyEmployee)
public class HourlyEmployee extends Employee { private double hourlyRate; public HourlyEmployee(String fName, String lName, String SSN, double rate) { // 显式调用父类构造,传递构造函数的参数 super(fName, lName, SSN); this.hourlyRate = rate; } }
测试代码验证
public class TestEmployee { public static void main(String[] args) { HourlyEmployee emp1 = new HourlyEmployee("John", "Doe", "123-45-6789", 25.5); System.out.println(emp1.getFirstName()); // 应该输出John,而非null SalariedEmployee emp2 = new SalariedEmployee("Jane", "Smith", "987-65-4321", 60000); System.out.println(emp2.getSSN()); // 应该输出987-65-4321,而非null } }
快速排查步骤
- 打开所有出问题的子类代码,检查构造函数是否第一行就调用了
super(正确的三个参数); - 核对父类构造函数的赋值语句,确保
this.属性名 = 参数名的写法没有错误; - 检查参数名的大小写和拼写,Java是大小写敏感的,
ssn和SSN是两个不同的变量。
如果按照这些步骤排查后还是有问题,可以把出问题的子类代码贴出来,我再帮你具体分析~
内容的提问来源于stack exchange,提问作者Aminu Bishir
相关产品推荐
相关产品推荐

