【问题标题】:Understanding inheritance of class variables理解类变量的继承
【发布时间】:2013-06-17 02:00:07
【问题描述】:

我正在用 Java 构建一个 Challenge24Solver 类。逻辑本身起作用并按预期找到解决方案(使用任意数量的参数)。无论如何,这部分项目按我的预期工作。

问题来自解决方案的表示问题。公平地说,我已经用 Python 完成了这个项目,并决定尝试用 Java 作为一种介绍,这可能是问题所在,我也在尝试像 Python 一样做这件事。

这是我的一些课程:

abstract class Operation { \\ Basic operation class
  static String token;
  abstract public double operate (double x, double y);
}
class AddOp extends Operation {
  static String token = "+";
  public double operate (double x, double y) {
    return x+y;
  }
}
//other operation classes SubOp, MulOp, DivOp
class Challenge24Step { // represents one step in a solution
  Operation operator;
  double x, y; //operands
  double value; //the value of the step (x operator y)
  public Challenge24Step (Operation operator, double x, double y) {
    this.operator = operator;
    // constructor code;
    }
  public String toString () {
    return String.format("%s %s %s = %s", this.x, this.operator.token, this.y,
                         this.value);
  }
}

问题是它仍然从 Operation 类中获取令牌:“null”

我知道这可能是因为 operator 被声明为 Operation,但我不明白为什么它不通过标准继承:实例、类、每个超类

如何重新排列脚本以便使用更具体的操作类的标记?

【问题讨论】:

    标签: java variables inheritance


    【解决方案1】:

    您不能在基类中将token 设为静态,因为这样每个继承的类都会有一个标记。您需要将其设为实例变量。你甚至不能把它放在静态方法中,因为 Java 中的 static 方法是不可覆盖的。

    在 Java 中,变量是不可覆盖的。如果继承一个类并添加一个同名变量,则派生类中的变量将隐藏,而不是覆盖基类中的变量。

    要解决此问题,请在基类中将 token 设为 abstract 方法,在派生类中提供实现,并返回所需的值。如果你这样做,你可以用接口替换抽象类,因为其中没有变量或实现:

    interface Operation { // Basic operation class
        String getToken();
        double operate (double x, double y);
    }
    class AddOp implements Operation {
        public String getToken() {return "+"; }
        public double operate (double x, double y) {
            return x+y;
        }
    }
    

    或者,将其保留在基中未分配,添加一个获取令牌值的构造函数,并将其分配到那里:

    abstract class Operation { // Basic operation class
        public final String token;
        abstract public double operate (double x, double y);
        protected Operation(String token) {this.token = token; }
    }
    class AddOp extends Operation {
        public AddOp() { super("+"); }
        public double operate (double x, double y) {
            return x+y;
        }
    }
    

    【讨论】:

    • 嘿,我做了 class Base{ x="s" } class Child extends Base{ x="x"} and main Base b = new Child(); Sysout(b.x) 并打印“s”
    • @nachokk 提到了同样的原因。变量不会被覆盖。只有方法被覆盖
    • 感谢您的解释和建议。我可能会使用第二个修复程序。目前我刚刚决定定义 public String toString () 以返回 clsName.token 保持令牌静态。也应该是抽象类 Operation {}
    • @PrasadKharkar 是的,我知道,但我认为它是隐藏的,所以如果我有 Child child = new Child() , sysout(child.x) 明显打印 x
    • 隐藏概念是什么意思?您能更具体一点并在这里提出一个新问题吗?我肯定会尽力解决您的问题:)。要求您提出不同的问题,因为隐藏概念与此问题中提出的内容略有不同
    【解决方案2】:

    静态变量通过引用。您已将operator 定义为Operation 类型,因此operator.token 指的是Operation.token

    我建议为此使用吸气剂:

    abstract Operation { \\ Basic operation class
      abstract public double operate (double x, double y);
      abstract public String getToken();
    }
    
    class AddOp extends Operation {
      public double operate (double x, double y) {
        return x+y;
      }
      public String getToken() {
          return "+";
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-06-09
      • 2015-12-09
      • 2021-08-29
      • 1970-01-01
      • 2013-04-19
      • 2018-08-13
      • 1970-01-01
      • 1970-01-01
      • 2018-02-24
      相关资源
      最近更新 更多