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
相关产品推荐
相关产品推荐

