class Base 

int i=99; 
public void amethod() 

System.out.println("llll"); 


public class GaiSJK extends Base 

int i=988; 
int c=2; 
public static void main(String arg[]) 

Base a= new GaiSJK(); 
System.out.println(a.i); 
a.amethod(); 
} public void amethod() 

System.out.println("ssss"); 

} 为什么a调用的方法是子类的,而变量却是父类的? 
请高手详解,越详细越好,谢谢!! 

解决方案 »

  1.   

    我也不懂,等楼下解答。PS:楼主我教你怎么贴代码:
    1、将代码作良好的格式化,以方便阅读。
    2、在发帖文本框的上方单击“#”按钮,选择 Java
    3、将代码粘贴到【code=Java】和【/code】之间。发出来的帖子就会是下面的效果:public class Hello {    // 程序入口
        public static void main(String[] args) {
            System.out.println("Hello!");
        }
    }
      

  2.   

    通过父类的变量访问子类的成员方法,只限于“覆盖”的情况发生时。也就是说,父类与子类的方法名称、参数个数与类型必须完全相同,才可以通过父类的变量调用子类的方法,你将子类中的amethod方法删掉,调用的将会是父类的方法,不知道你明白了没有
      

  3.   

    用父类的引用指向子类的对象
    GaiSJK的amethod()覆盖Base的amethod(),你定义的对象是new GaiSJK(); ,那么在调用方法的时候,调用的是子类的GaiSJK.amethod();如果调用的是成员变量的时候,则是根据你的引用(Base a)来调用成员变量,此时你的引用是Baer。
      

  4.   

    同时,GaiSJK的amethod()覆盖Base的amethod(),父类Base必须有amethod()方法,否则报错,你可以试一试,把Base.amethod()删除
    这是因为,1、你的引用是Base,base.amethod()不存在;2、父类的引用Base 不能跨越自己的权限,去访问子类的方法
    所以,用父类的引用指向子类的对象,在父类的引用调用方法时,父类必须实现该方法,调用的什么,如果子类覆盖了父类的方法,则调用子类的方法,如果没有覆盖,则调用自身(父类)的方法
      

  5.   

    java的方法调用采用的是动态绑定方法,Java有一个存放类实例方法地址的数据结构,叫方法表(Method Table),一个类的所有对象共享一个方法表,且派生类中继承于基类的方法在方法表中的偏移量跟该方法在基类方法表中的偏移量保持一致。
    GaiSJK 在继承Base的时候,重写了方法amethod(),这个信息将在Method Table中反映,所以你在把GaiSJK 对象实例转换成Base类型后,方法表并未改变,所以调用的是之类的方法。但是由于属性a在父类和子类的数据结构中都各自占有空间,所以调用的是父类的属性。不知道这样解释对不对
      

  6.   

    为什么a调用的方法是子类的,而变量却是父类的? 
    因为这是多态中的向上转型,也就是说虽然你申明的是 Base a,但是却是new 的子类GaiSJK,这样的话用C++里的话说就是指针指向的是子类的地址,所以理所当然应该是调用子类的方法(前提是子类覆盖掉父类的方法),如果没有覆盖,就会调用父类的方法,因为继承本身就是把父类的方法再重用一遍了。
      

  7.   

    首先,lz要清楚
    java中的多态是方法的多态,而不是字段的多态当GaiSJK继承Base时
    方法amethod()被override
    但字段i并没有被覆盖,而是保留一个副本存在子类GaiSJK中
    也就是说子类GaiSJK的amethod()是自己的,以区别于他的父类
    而字段i有两个,一个是自己的,还有一个是他爸爸给的
    如果GaiSJK还有更深层次的祖先类,并且每个类都定义了字段i
    那GaiSJK就有来自所有继承类的字段i的副本Base a= new GaiSJK(); 
    这时候a这个引用指向的是子类的对象
    a.amethod(); 调用的肯定是子类的方法
    这就是多态,这是毫无疑问的
    a.i中由于a是父类引用,并且在GaiSJK中有父类字段i的值
    所以a.i得到是父类的值,而不是子类的值
      

  8.   

    这个地方设计得也还是有点晦涩,这种东西只能从调试中去自圆其说,做工程的话,不行就调罢.这也是JAVA10%非纯粹OO之一吧.
      

  9.   

    这个问题牵扯到Java中最核心的机制,即动态绑定或者叫多态机制:
    内存空间中,子类对象空间中包含个父类对象,类对象中好似有个指针指向代码区中要执行的方法代码(code),java的多态机制规定这个指针要根据实际new出来的对象来决定指向谁的方法code.本例中,父类Base引用a1指向了子类GaiSJK对象,给a1 new出来的是GaiSJK对象,所以在a1.amethod()调用的是子类的;我们又注意到,在内存中new GaiSJK()出来的对象和其中包含的父类对象都含有i属性,但是对于a1可见的只有父类中的i,所以在调用时就是父类的
      

  10.   

    Base a= new GaiSJK(); 上转型,这样使用子类的变量,父类的方法.