【问题标题】:Why am I not inheriting the superclass variable?为什么我不继承超类变量?
【发布时间】:2016-07-30 23:00:51
【问题描述】:

我正在输出

SubClass subClass = new SubClass(4);
System.out.println(subClass.getVal());

使用这两个类:

public class SuperClass {
    public int x = 99;

    public int superClassMethod() {
        return -1;
    }
}


public class SubClass extends SuperClass {
    public int x;

    public SubClass(int value) {
        x = value;
    }

    public int getVal() {
        return x;
    }
}

这会按预期输出4。但是假设我在SubClass 构造函数中注释掉了x = value 行。为什么它输出0(我假设未启动变量的默认值)而不是继承自超类的99

如果我将return x 更改为return superClassMethod();,它似乎正确地从超类中拉出-1。那么为什么是方法而不是变量呢?

【问题讨论】:

  • SubClass 中x 的默认值为0,省略SubClass 中的减速,您将拥有99

标签: java oop inheritance superclass


【解决方案1】:

当变量在不同范围内的名称冲突时,它总是使用最近范围内的变量,即使它尚未设置为任何值。

要区分其他范围内的变量,请在变量前加上thissuper

public class SuperClass {
    protected int x;
}
public class SubClass extends SuperClass {
    private int x;
    public SubClass(int x) {
        x = 2; // sets the parameter variable
        this.x = 2; // sets the instance variable
        super.x = 2; // sets the super class' instance variable
    }
}

【讨论】:

  • 这个答案很棒,因为它还说明了一个相关的场景,即本地范围覆盖同一类的成员变量。
  • 有什么理由把x传给method()吗?无论如何它都会被覆盖。我不能改用int x = 2; 吗?
  • x 放在参数中而不是int x = 2; 的唯一原因是,当人们为参数创建与实例变量同名的setter 方法时,这是一个典型的问题.
  • 你的意思是像void setX(int x) { this.x = x;}这样的东西吗?
  • 不完全。我可能应该在那里放置一个构造函数。
【解决方案2】:

public int x; 行表示名为x 的变量的新定义。因此,您将在类中有两个名为 x 的变量 - 一个在 SuperClass 中,另一个在 SubClass 中。它们具有不同的位置,因此可以包含不同的值。因为你没有初始化SubClass中的那个,所以它的默认值是0

如果您完全删除SubClass 中的声明,则任何从SubClassx 的访问都会从父类访问变量x

【讨论】:

  • 那么如果我在子类中声明了x,我将如何获得父类的x 值? this.xsuper.x?
  • 请注意——你真的不应该声明两个相互隐藏的变量。这不是很好的做法。只需将它们命名为两个不同的东西(变量通常应该比 x 更具描述性)。 @ZbynekVyskovsky-kvr000 的答案会起作用,所以我投了赞成票,但总的来说这不是一个好主意。
【解决方案3】:

您正在继承,但您在子类中明确重新声明 x 会覆盖子类范围内的 x

SubClass 中省略public int x;,应该没问题。

【讨论】:

    【解决方案4】:

    这都是因为这段代码。

    public SubClass(int value) { //what ever You pass you will get the result.
            x = value;
        }
    

    这里x是一个实例变量所以,在继承中,只有Methods被允许是override而不是Instance Variable所以,如果new SubClass()被使用,x将由0初始化。 或者,xvalue 如果 new SubClass(int value) 已使用。

    你在打电话

    SubClass subClass = new SubClass(4);  //initialize your local x with 4
    System.out.println(subClass.getVal());    // Result you will get is 4
    

    【讨论】:

      【解决方案5】:

      问题是您的子类也有一个同名 x 的 int。然后它将打印该默认值,而不是您的超类的默认值。

      尝试删除该 int,它应该可以工作!

      【讨论】:

        【解决方案6】:

        你在子类和超类中都有一个成员,在对象子类的实例中,可见的x是你在子类中定义的那个,如果你需要超类 x 你需要使用 super 关键字。

        因此,在该范围内唯一有效的 x 是 子类

        中的实例之一

        【讨论】:

          【解决方案7】:

          因为x 里面的SubClassshadowing variable。也就是说,它隐藏了 SuperClass 变量x。所以你不能从 SuperClass 中获得价值。当您评论 x = value; 时,它会返回 int 类成员的默认值,即 0

          【讨论】:

          • 不,您仍然可以访问超类中的变量。查看其他答案
          • @4castle 绝对可以使用super 关键字访问!但 OP 并没有这样做。当我们只使用名称调用变量时,超类变量被子类隐藏。这就是我试图解释的。 :)
          【解决方案8】:
          public class SubClass extends SuperClass {
              public int x;   // this line hides the x defined in the super class.
              ...
          
              public int getVal() {
                  return x;
              }
          }
          

          因为 SubClass 中的 x 隐藏了 SuperClass 中定义的 x,又因为没有指定作用域

          return x;
          

          javac 将其翻译为

          return this.x;
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-02-03
            • 2011-03-25
            • 2015-09-02
            • 2014-10-06
            • 2015-08-11
            • 2023-01-19
            • 2018-07-07
            • 2010-10-20
            相关资源
            最近更新 更多