在子类之外访问的Java超类变量?

问题描述 投票:-1回答:2

如果我有三个课程如下:

package com.Bob.Marley;
public class SuperClass{
     protected int x = 0;
}

package com.Bob.Marley;
public class SubClass extends SuperClass{
    protected int x = 1;
}

package com.Bob.Marley;
public class TestClass{
    public static void main (String[] args){
        SubClass s = new SubClass();
        //print 1
        System.out.println(s.x);
        //how do I print the superclass variable?
        //I know inside SubClass I can access it with plain old super.x
        //but what about outside the subclass with a new object. 
    }
}

所以问题是如何从一个单独的类中创建的新对象的超类中打印出0。的System.out.println(s.super.x);不起作用。我不认为它会改变任何东西,但我使用的是java 8。

java inheritance super
2个回答
0
投票

表达式s.super.x在这里无效。无论何时用super.x作为前缀,它都应该是类型名称,而不是变量名称,例如SuperClass.super.x。但是,这仅在子类内有效,用于访问封闭类的超类,此处不存在。

x变成一个SuperClass所以你可以访问在x宣布的Superclass

System.out.println( ((SuperClass) s).x);

要么

SuperClass sc = (SuperClass) s;
System.out.println(sc.x);

这是有效的,因为变量访问是静态绑定的。变量或表达式的类型确定搜索变量访问的范围。


0
投票

TL; DR:如果在子类中引入新字段,请不要重用父类中的字段名称。你什么都得不到,只有困惑和问题。

如果我理解正确,你希望SubClass实例有两个字段,一个继承自SuperClass(讨论,让我们将其重命名为superX以使事情更清楚),一个来自子类本身(让我们将其重命名为subX)。

对于给定的SubClass实例,您希望能够访问两个字段,superXsubX(当然,使用不同的表达式)。在您的代码示例中,使事情变得困难的是,您选择为它们提供相同的名称x

所以,如果你真的希望你的实例携带两个字段,我建议重命名它们,这样你就不必使用丑陋的技巧,比如投射到SuperClass

public class SuperClass{
     protected int superX = 0;
}

public class SubClass extends SuperClass{
    protected int subX = 1;
}

但是,如果x代表同一属性对于超类和子类具有相同的含义,只是具有不同的初始值,那么有两个不同的字段没有意义,你应该将代码更改为:

public class SuperClass{
     protected int x = 0;
}

public class SubClass extends SuperClass{
    // constructor initializes the x field with 1.
    public SubClass(){
        x = 1;
    }
}

当然,从SubClass的单个实例中获取两个不同的值是不可能的。

© www.soinside.com 2019 - 2024. All rights reserved.