子类toString访问父类私有属性报错,如何解决?
问题描述
设定vehicle为父类,car为其子类,代码如下:
父类vehicle代码
public abstract class vehicle { private String imatriculation ; private int nb_chevaux ; private double consomation ; public vehicle(String imatriculation , int nb_chevaux , double consomation){ this.imatriculation = imatriculation ; this.nb_chevaux = nb_chevaux ; this.consomation = consomation ; } public abstract void setconsomation(int conso_input ); }
子类car代码
public class car extends vehicle { public car(String imatriculation,int nb_chevaux,double consomation){ super(imatriculation ,nb_chevaux , consomation ) ; } @Override public void setconsomation(int conso_input ){ this.consomation = conso_input ; } @Override public String toString(){ return "car" + this.imatriculation + " " + this.nb_chevaux + " " + this.consomation ; } }
编译时toString方法因访问vehicle类的私有属性报错,疑惑使用super是否能解决该问题,询问解决方法及是否必须使用getter方法。
解决方案
报错原因
Java里私有(private)成员只能被定义它的类本身访问,子类哪怕直接继承父类,也无权直接碰父类的私有属性——不管用this还是super都不行,super只能调用父类的非私有成员、构造方法或者重写的方法,私有成员对它来说完全不可见。
可行解决方法
目前有两种常用方案:
- 给父类添加Getter(Setter)方法(推荐)
这是符合Java封装原则的标准做法,在父类vehicle中为每个私有属性添加对应的Getter方法,同时完善Setter逻辑:
public abstract class vehicle { private String imatriculation ; private int nb_chevaux ; private double consomation ; public vehicle(String imatriculation , int nb_chevaux , double consomation){ this.imatriculation = imatriculation ; this.nb_chevaux = nb_chevaux ; this.consomation = consomation ; } // Getter方法:对外提供属性访问入口 public String getImatriculation() { return imatriculation; } public int getNb_chevaux() { return nb_chevaux; } public double getConsomation() { return consomation; } // 实现抽象的Setter方法,也可以保留抽象让子类自己实现 @Override public void setconsomation(int conso_input ){ // 注意:参数是int,属性是double,这里做自动类型转换 this.consomation = conso_input; } }
然后子类代码修改为通过Getter访问属性:
public class car extends vehicle { public car(String imatriculation,int nb_chevaux,double consomation){ super(imatriculation ,nb_chevaux , consomation ) ; } @Override public void setconsomation(int conso_input ){ // 可以直接调用父类的实现,也可以自定义逻辑 super.setconsomation(conso_input); } @Override public String toString(){ return "car " + getImatriculation() + " " + getNb_chevaux() + " " + getConsomation() ; } }
- 将父类属性改为protected修饰
如果不需要严格的封装,或者只是简单场景快速解决,可以把父类的属性修饰符从private改成protected——protected允许子类和同包类直接访问:
public abstract class vehicle { protected String imatriculation ; protected int nb_chevaux ; protected double consomation ; // 构造方法和抽象方法保持不变 }
这样子类里的toString和setconsomation方法不用修改就能编译通过,但这种方式会破坏封装,正式项目里不建议大量使用。
是否必须用Getter?
不是必须,但非常推荐用Getter,原因如下:
- 符合面向对象的封装思想,能控制属性的访问逻辑(比如返回时做格式校验或转换)
- 后续如果属性的存储方式改变,只需要修改Getter方法,不用改所有调用的地方
- 提升代码的可维护性和扩展性
如果是临时测试或者极其简单的场景,用protected也能解决,但从代码规范和长期维护来看,Getter是更好的选择。
内容的提问来源于stack exchange,提问作者Marouane Sharry
相关产品推荐
相关产品推荐

