有两个类 Employee(超类)和Manager(子类).子类有特有的setBound()方法Manager[] managers = new Manager[10];Employee[] staff = managers;staff[0] = new Employee();此时我managers[0].setBound()方法,会报错么!为什么

解决方案 »

  1.   

    为什么呢?能告诉我具体的原因么!staff[0] = new Employee(); 指向的是另外一块内存啊~!与managers[0].setBound();没什么关系吧我就是这样认为才会有疑惑..还希望能帮我解答下..谢谢了
      

  2.   

    这个错编译的时候应该不会有吧 应该是在运行的时候出错吧
    出错的代码应该是staff[0] = new Employee(); 
      

  3.   

    这句代码不会有任何问题.但是你用Manager的对象去调用Manager自己独有的setBound()时候就会出错.如果不是对象数组就没有任何问题.我这里的疑惑就是怎么改变的Staff[0]在栈内存中的指向.Manager[0]的指向怎么也跟这变了...也就是staff[0] = new Employee(); 之后 Manager[0]却指向一个Empolyee对象.按我的理解只有staff[0]指向一个Employee对象啊!Manager[0]的指向应该没有变才对啊!!!希望大家能发扬共享精神,把你们的知识拿出来分享下.
      

  4.   

    我来讲讲看你能不能看懂,
    Manager[] managers = new Manager[10]; 
    上面这句话执行完后会在堆上开辟十个存储空间的内存,然后由managers指向这个数组的首地址;
    Employee[] staff = managers; 
    上面这句话执行完后,把数组的首地址赋给了staff变量,也就是说staff和managers指向的是相同的地址staff[0] = new Employee(); 所以运行的时候就会出错,因为staff指向的是子类new Managers[10]时开辟的空间,他的大小只能装子类变量
    而不能装父类new出的实例。r如果把staff[0]=new Manager();就没问题了,关键是会画内存就好理解了
      

  5.   

    因为staff指向的是子类new Managers[10]时开辟的空间,他的大小只能装子类变量; 
    你说的其它的我都明白.我在疑惑的就是这一句.
    是不是对象数组在堆内存中分配空间后就不会在动了.
    打个比方:
    staff[0]原来指向的是Manager[0]
    现在staff[0] = new Employee();这个内存是不是强占Manager[0]的内存空间,也就是覆盖调Manager[0],现在这块地方就是装Employee[0].如果不是这样子这个问题就解释不通啊!
      

  6.   

    staff[0]的类型是Manager,这个类型不存在setBound方法.
    如果要使用子类特有的方法,就不要这么声明.
    或者进行强制类型转换之后再调用.
      

  7.   

    关于内存的说法这么理解根本就不对,不要"明白" 了.
    学java不用整天关注这些内存的问题.
      

  8.   

    先理解什么是多态,父类的引用指向子类的对象,调用方法的时候调用的是实际对象的相应方法,也就是说子类要重写父类的方法.
    你这里却要让父类的引用来调用父类没定义的方法,编译器就不让你通过,因为它找不到Manager中定义的setBound()方法.
    还没到运行阶段呢,内存的问题就先别分析了
      

  9.   

    你的程序会报ArrayStoreException异常。因为你调用managers[0].setBound()的时候,jvm会判断managers[0]是不是一个Manager对象,如果不是则抛出上面的异常以表示数组中保存了一个错误的类型。
      

  10.   

    Manager[0]此时怎么就不是Manager对象了呢!我明明改变的是staff[0] = new Employee();
    疑惑就在这里!
      

  11.   

    你改变了staff[0] = new Employee(); 这个,此时Manager[0]中也存的是Employee对象,而不是Manager对象。用staff[0] = new Manager(); 就好了。
      

  12.   

    也不是你说的这个样子吧!我今天特意把代码写出来看了一下:我是这样理解的,不知道对不对
    staff[0] = new Employee(); 
    这里的staff[0]原来装的是Manager[0]的引用,现在你要把Employee对象的引用赋值给Manager对象的引用会出现向下类型转换错误!也就是装staff[0](栈内存)的地方不适合装Employee对象的引用,所以这个代码运行时会报错...
    不晓得我的理解正步正确,希望各位能给指正下..3Q 
      

  13.   

    从楼主提出的问题看,楼主要注意的知识点很多:
    1、最直接的一个问题:class Point { int x, y; }
    class ColoredPoint extends Point { int color; }
    class Test {
    public static void main(String[] args) {
    ColoredPoint[] cpa = new ColoredPoint[10];
    Point[] pa = cpa;
    System.out.println(pa[1] == null);
    try {
    pa[0] = new Point();
    } catch (ArrayStoreException e) {
    System.out.println(e);
    }
    }
    }
    你看是不是你的问题?
    如果是你的老师出的题目,你看一下Java Language Specification 10.10 Array Store Exception2、现在抛开对象数组,仅仅看:
            Manager m = new Manager();
            Employee e =new  Employee();
            e= m;
            e.setBound();     你需要知道“e.setBound();”语句为什么编译错误。
      

  14.   

    3、
    楼主在2楼说:“staff[0] = new Employee(); 指向的是另外一块内存啊~!”
    谁指向什么内存?谁与谁指向的是不同内存?4.真正的问题是:
        static void foo(){
            Manager[] managers = new Manager[10];
            Employee[] staff = managers;
            staff[0] = new Manager(); 
            staff[0].setBound();//编译错误
        }解答:
    1、staff是Employee[]类型变量,它的元素都是Employee类型变量。
    2、staff = managers后,staff的元素如staff[0]仅仅能够被赋与managers的类型的值即Manager对象。(At compile time, an assignment to an element of pa is checked to make sure that the value assigned is a Point. But since pa holds a reference to an array of ColoredPoint, the assignment is valid only if the type of the value assigned at run-time is, more specifically, a ColoredPoint. )
    3、但是,staff[0]虽然只能赋予Manager对象的引用,它还是一个Employee类型的变量——丧失子类特性。
      

  15.   

     static void foo(){ 
            Manager[] managers = new Manager[10]; 
            Employee[] staff = managers; 
            staff[0] = new Employee(); 
            staff[0].setBound();//编译不会有错误,运行时错误. 
        } 
    其实开始我没有把代码写出来,所以才会有那么乱七八糟的问题.真正的问题在于
    staff[0] = new Employee(); //父类引用给子类引用,向下类型转换失败.
    其实就是这条规则,父类有的子类一定有,子类有的父类不一定都有.现在你要把父类引用给子类,肯定会出问题.