【问题标题】:How does Java handle fields when upcasting? [duplicate]Java 在向上转换时如何处理字段? [复制]
【发布时间】:2013-01-02 20:10:51
【问题描述】:

可能重复:
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。我对方法的工作很清楚:如果为SuperClass 定义了给定的方法,我将只能使用SubClass 的方法。

但是,当我尝试访问testmyString 时,我不知道为什么使用SuperClass 的字段。由于testSubClass 的一个实例,我希望使用SubClass 中定义的myString,为什么这没有发生?我错过了什么?

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

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

SubClass 中,所以我的问题主要是关于SuperClass 的字段如何在test 中使用。也许我遗漏了一些明显的东西?

我尝试搜索答案,发现最接近的主题是Upcasting in Java and two separate object properties,虽然有帮助,但没有回答我的问题。

提前致谢

【问题讨论】:

    标签: java


    【解决方案1】:

    属性不能像方法一样被重载。

    test.myMethod(); 
    

    这里的方法调用取决于实际对象的类型。这里的对象是SubClass 类型的,所以SubClass 的方法被调用了。

    test.myString
    

    访问属性时,取决于引用变量的类型。这里引用变量,即test 的类型为SuperClass,因此可以访问来自SuperClass 的属性。

    你正在寻找的是class variable hiding / shadowing

    【讨论】:

    • 不错的链接,谢谢。关键部分是:“当子类中的实例变量与超类中的实例变量同名时,则在作为引用类型的类中选择实例变量。”
    • @Akavall:你说得对:)
    【解决方案2】:

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

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

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

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

    Java 语言规范:

    如果类声明了一个具有特定名称的字段,那么 据说该字段的声明隐藏了所有可访问的 在超类中声明具有相同名称的字段,以及 类的超接口。

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

    【讨论】:

      猜你喜欢
      • 2021-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-05
      • 2018-11-04
      • 2020-08-24
      • 1970-01-01
      • 2017-04-03
      相关资源
      最近更新 更多