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

Aka*_*all 6 java

可能重复:
阴影的概念

我很困惑在向上转换期间如何在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);

    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

Method in SubClass
String in SuperClass //Why is "String in SubClass" not used?
Run Code Online (Sandbox Code Playgroud)

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

不过,我很失落,为什么的一个领域SuperClass,当我尝试访问使用myStringtest.由于test是实例SubClass我希望myString定义中SubClass使用,这是为什么没有发生?我错过了什么?

我知道我可以SubClass通过使用this运算符来访问myString .例如,我可以printMyString在SuperClass中定义方法,并用它覆盖它

public void printMyString()
{
    System.out.println(this.myString);
}
Run Code Online (Sandbox Code Playgroud)

SubClass,所以我的问题主要是关于现场的怎么来SuperClass被使用test.也许我错过了一些明显的东西?

我试图寻找答案,我发现的最接近的主题是Java中的Upcasting和两个独立的对象属性,虽然有用,但它没有回答我的问题.

先感谢您

xyz*_*xyz 7

属性不能像方法一样重载.

test.myMethod(); 
Run Code Online (Sandbox Code Playgroud)

这里方法调用取决于实际对象类型.这里的对象是类型,SubClass因此SubClass调用方法.

test.myString
Run Code Online (Sandbox Code Playgroud)

访问属性时,它取决于引用变量类型.这里引用变量ie test是类型,SuperClass因此SuperClass访问属性from .

您正在寻找的是类变量隐藏/阴影.


Rah*_*hul 5

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

重写意味着应该根据对象的运行时类型而不是声明的类型来调用成员。

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

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

Java语言规范:

如果类声明了具有特定名称的字段,则该字段的声明被认为隐藏了超类和该类的超接口中具有相同名称的字段的所有可访问声明。

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