Java继承中调用父类order方法遇静态引用错误,如何解决?
问题解决方案
错误原因
- 静态成员(如
Americano、CaffeLatte这类静态变量)属于类级别,在类加载阶段就会初始化,但c1是Parent的实例变量,只有创建Parent对象时才会存在。类加载时c1尚未初始化,静态成员直接引用它就会触发"Cannot make a static reference to the non-static field c1"错误。 Child1是Parent的非静态内部类,创建它的实例必须依赖Parent的实例,直接在Parent类中声明Child1 c1 = new Child1()会导致循环依赖(Child1继承Parent,创建Child1需先初始化Parent,而Parent实例初始化又要创建Child1)。
下面提供两种可行的修复方案:
方案一:将咖啡价格设为静态常量(推荐)
如果咖啡价格是固定值,无需依赖实例,直接在Parent类中定义静态常量,并将内部类改为静态内部类(摆脱对外部类实例的依赖):
class Parent { // 直接定义静态常量,无需依赖Child1实例 public static final int AMERICANO = 100; public static final int CAFFE_LATTE = 125; public static final int CAPPUCCINO = 150; static void order() { // some statements about choosing which coffee System.out.println("Ordering coffee..."); } // 改为静态内部类,不依赖Parent实例 static class Child1 extends Parent { public Child1() {} } class Child2 extends Child1 { public Child2() { Parent.order(); // 调用静态方法完全合法 } } public static void main(String[] args) { // 创建Child2实例需依赖Parent实例 Parent parent = new Parent(); Child2 child2 = parent.new Child2(); } }
方案二:保留实例变量设计
如果必须保留实例变量的逻辑,将Parent的咖啡价格改为实例变量,并在构造方法中初始化c1以避免循环依赖:
class Parent { Child1 c1; // 在构造方法中初始化c1,规避循环依赖 public Parent() { c1 = new Child1(); } // 改为实例变量,而非静态 public int Americano; int CaffeLatte; int Cappuccino; static void order() { // some statements about choosing which coffee System.out.println("Ordering coffee..."); } class Child1 extends Parent { int Americano = 100; int CaffeLatte = 125; int Cappuccino = 150; public Child1() {} } class Child2 extends Child1 { public Child2() { Parent.order(); // 调用静态方法正常执行 } } public static void main(String[] args) { Parent parent = new Parent(); // 手动将Child1的价格赋值给Parent实例变量 parent.Americano = parent.c1.Americano; parent.CaffeLatte = parent.c1.CaffeLatte; parent.Cappuccino = parent.c1.Cappuccino; Child2 child2 = parent.new Child2(); } }
关键说明
你原本在Child2中调用Parent.order()的逻辑是合法的,因为order是静态方法,可直接通过类名调用。前面的编译错误完全是静态变量引用非静态实例导致的,修复该问题后,这个调用就能正常执行。
内容的提问来源于stack exchange,提问作者Kazumi Aoi
相关产品推荐
相关产品推荐

