Java如何在向上转换时处理字段?

时间:2013-01-01 06:22:39

标签: java

  

可能重复:
  The concept of shadowing

我很担心在上传期间如何在Java中处理类的字段。例如:

class SuperClass
{
    String myString = "String in SuperClass";

    public void myMethod()
    {
        System.out.println("Method in SuperClass");
    }
}

class SubClass extends SuperClass
{
    String myString = "String in SubClass";

    public void myMethod()
    {
        System.out.println("Method in SubClass");
    }
}

class Question
{
    public static void main(String[] args)
    {
        SuperClass test = new SubClass();
            // object test is an instance of SubClass
            // but I am telling the compiler to treat it as SuperClass

        test.myMethod();
        System.out.println(test.myString);

    }
}

输出:

Method in SubClass
String in SuperClass //Why is "String in SubClass" not used?

当我创建一个对象test时,它是SubClass类的一个实例;但是,我告诉编译器将其视为SuperClass。关于方法的工作,一切都很清楚:如果为SubClass定义了给定的方法,我将只能使用SuperClass的方法。

但是,当我尝试访问SuperClass myString时,我迷失了test字段的原因。由于testSubClass的实例,我希望myString中定义的SubClass被使用,为什么不会发生这种情况?我错过了什么?

我知道我可以使用SubClass运算符访问this的myString。例如,我可以在SuperClass中定义printMyString方法,并用

覆盖它
public void printMyString()
{
    System.out.println(this.myString);
}

SubClass中,我的问题主要是SuperClass如何使用test的字段。也许我错过了一些明显的东西?

我试图搜索答案,我找到的最接近的主题是Upcasting in Java and two separate object properties,虽然有帮助,却没有回答我的问题。

提前感谢

2 个答案:

答案 0 :(得分:7)

属性不能像方法那样重载。

test.myMethod(); 

此处方法调用取决于实际对象的类型。此处对象的类型为SubClass,因此调用SubClass的方法。

test.myString

访问属性时,它取决于类型的引用变量。这里引用变量ie test的类型为SuperClass,因此访问SuperClass的属性。

您所看到的是class variable hiding / shadowing

答案 1 :(得分:3)

Java中的字段仅隐藏且实际上未被覆盖(这并不意味着我们在尝试此操作时会遇到编译时错误,而是在真正意义上不会覆盖它们)。

  

覆盖意味着应该根据运行时调用该成员   对象的类型而不是基于声明的类型。

但Java中字段的绑定始终是静态的,因此它仅基于声明的对象引用类型

在您给出的示例中,通过在类SubClass中声明名为“myString”的类变量,您可以隐藏它将从其超类SuperClass继承的类变量,并使用相同的名称'的myString'。

Java语言规范:

  

如果类声明了具有特定名称的字段,那么   据说该领域的声明隐藏任何和所有可访问的   超类中具有相同名称的字段的声明,和   班级的超级接口。

     

如果隐藏字段是静态的,则可以使用限定名称,或者使用包含关键字super或强制转换为超类类型的字段访问表达式来访问隐藏字段。