You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

子类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只能调用父类的非私有成员、构造方法或者重写的方法,私有成员对它来说完全不可见。

可行解决方法

目前有两种常用方案:

  1. 给父类添加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() ; 
    }
}
  1. 将父类属性改为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 13:45:26