大树先生 2016-02-01 14:17 采纳率: 100%
浏览 1998
已采纳

stackoverflow上面的java的域不能“重写”问题

package test;

class A 
{
    int x = 5;
} 
class B extends A 
{
    int x = 6;
} 
public class CovariantTest 
{
    public A getObject() 
    {
       return new A();
    } 
    public static void main(String[]args) 
    {
       CovariantTest c1 = new SubCovariantTest();
       System.out.println(c1.getObject().x);
    }
}

class SubCovariantTest extends CovariantTest 
{
    public B getObject() 
    {
       return new B();
    }
}

最后输出的答案是5不是6
stackoverflow上面的解释我看了还是不太理解。
1.成员变量是编译时决定我了解,但这与“c1.getObject().x”有什么关系?毕竟c1.getObject()返回的是类B的对象呀?
2.解释里提到了隐藏域,子类的域会隐藏父类同名域,和重写是不一样的。我不太明白这个与答案有什么联系?

stackoverflow的问题地址:
http://stackoverflow.com/questions/12589274/slight-confusion-regarding-overriding-where-variables-are-concerned

  • 写回答

1条回答

  • threenewbee 2016-02-01 14:58
    关注

    提到了隐藏域,子类的域会隐藏父类同名域,和重写是不一样的。我不太明白这个与答案有什么联系
    这就是说两个变量都叫x,但是是两个我完全不同的变量,既然不同的变量,干脆我们就用不同的名字。
    看下面的代码,我把派生类的x修改为y,使得派生类的x叫做y

     /* package whatever; // don't place package name! */
    
    import java.util.*;
    import java.lang.*;
    import java.io.*;
    
    class A 
    {
        int x = 5;
    } 
    class B extends A 
    {
        int y = 6;
    } 
    
    class SubCovariantTest extends CovariantTest 
    {
        public B getObject() 
        {
            System.out.println("sub getobj");
           return new B();
        }
    }
    /* Name of the class has to be "Main" only if the class is public. */
    class CovariantTest 
    {
        public A getObject() 
        {
            System.out.println("ct getobj");
           return new A();
        } 
    
        public static void main (String[] args) throws java.lang.Exception
        {
            // your code goes here
            CovariantTest c1 = new SubCovariantTest();
            System.out.println(c1.getObject().y);
        }
    }
    

    现在这代码没办法编译了。

    System.out.println(c1.getObject().x);
    可以编译。

    说明派生类定义的那个变量,编译器根本就不承认它的存在。为什么如此?因为

    public B getObject() 
    {
        System.out.println("sub getobj");
       return new B();
    }
    

    你一厢情愿把返回值写成B,但是它仍然只能返回A

    这个叫做协变式覆盖

    http://blog.csdn.net/kiss_the_sun/article/details/7846413

    所以它返回的其实还是被当作A,既然是A,那么显然B定义的类型不作数了。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?