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

Java继承中对象输出异常:子类无法赋值父类变量的原因与解决

子类无法给父类变量赋值的原因及修复方案

问题根源

你这段代码里犯了一个很典型的对象独立性错误——Oxford o、Mc m和Book b是三个完全独立的对象,它们各自拥有Book类定义的所有成员变量(op、mp、name、auther)的独立副本:

  • 调用o.price(300)时,修改的是o这个对象自己的op值;
  • 调用m.price(400)时,修改的是m这个对象自己的mp值;
  • 但最后你调用的是b.Display(),输出的是b这个对象自己的变量,而b的op和mp从来没被赋值过,自然保持默认的0了。

修复方案(两种思路)

根据你的期望输出,核心是要让同一个Book对象的op和mp被正确赋值,这里给你两种可行的修改方式:

思路1:复用同一个对象(推荐)

既然要展示同一本书的两个价格,完全没必要创建三个独立对象。可以用一个子类对象(因为子类继承了Book的所有属性和方法)来完成所有设置,最后调用输出方法:

class Book {
    int op, mp;
    String name, auther;

    // 遵循Java命名规范:方法名首字母小写
    void setData(String n, String au) {
        name = n;
        auther = au;
    }

    void display() {
        System.out.println("Name: " + name);
        System.out.println("Auther: " + auther);
        System.out.println("oxford price: " + op);
        System.out.println("mc price: " + mp);
    }
}

// 子类负责设置对应渠道的价格
class Oxford extends Book {
    void setOxfordPrice(int p) {
        this.op = p; // 子类继承了op变量,直接用this访问即可
    }
}

class Mc extends Book {
    void setMcPrice(int p) {
        this.mp = p;
    }
}

public class Sai {
    public static void main(String args[]) {
        // 创建一个Oxford对象,它拥有Book的所有属性
        Oxford targetBook = new Oxford();
        targetBook.setData("Java", "Robert");
        targetBook.setOxfordPrice(300);
        
        // 用Mc对象设置mc价格,再把值同步给targetBook
        Mc mcPriceSetter = new Mc();
        mcPriceSetter.setMcPrice(400);
        targetBook.mp = mcPriceSetter.mp;
        
        // 输出最终结果
        targetBook.display();
    }
}

思路2:让子类直接操作目标Book对象

如果希望子类专门负责对应价格的设置,可以修改子类方法,让它们接收一个Book对象作为参数,直接修改该对象的属性(这种方式不需要子类继承Book,改为静态工具类更合理,这里保留原继承结构做演示):

class Book {
    int op, mp;
    String name, auther;

    void setData(String n, String au) {
        name = n;
        auther = au;
    }

    void display() {
        System.out.println("Name: " + name);
        System.out.println("Auther: " + auther);
        System.out.println("oxford price: " + op);
        System.out.println("mc price: " + mp);
    }
}

class Oxford extends Book {
    // 接收目标Book对象,直接修改它的op属性
    void setOxfordPrice(Book targetBook, int p) {
        targetBook.op = p;
    }
}

class Mc extends Book {
    // 接收目标Book对象,直接修改它的mp属性
    void setMcPrice(Book targetBook, int p) {
        targetBook.mp = p;
    }
}

public class Sai {
    public static void main(String args[]) {
        Book b = new Book();
        b.setData("Java", "Robert");
        
        Oxford o = new Oxford();
        o.setOxfordPrice(b, 300); // 直接修改b的op值
        
        Mc m = new Mc();
        m.setMcPrice(b, 400); // 直接修改b的mp值
        
        b.display();
    }
}

小建议

  • 遵循Java命名规范:方法名首字母小写(比如setData而非Setdata),变量名尽量见名知意,这样代码可读性更高;
  • 如果子类只是单纯用来设置某个属性,其实没必要继承Book,改成静态工具类会更合理,避免不必要的继承关系。

内容的提问来源于stack exchange,提问作者Seshasai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:14:38