黑马程序员技术交流社区

标题: 请大神详细解答它的运行机理 [打印本页]

作者: kmlitheima    时间: 2015-6-4 10:16
标题: 请大神详细解答它的运行机理
  class A {
            void fun1() {
                      System.out.println(fun2());
                }
                int fun2() {
                        return 123;
                }
        }
         public class B extends A {
                int fun2() {
                         return 456;
                 }
              public static void main(String args[]) {
                        B b = new B();
                        b.fun1();//这里为嘛调用子类方式
                        A a = b;
                        a.fun1();//这里又是怎么使用子类的呢?它的原理和运行方式,请详细解答????
                }
        }

作者: 经济    时间: 2015-6-4 11:11
b.fun1();//这里为嘛调用子类方式     ----- 调用b.fun1(),执行System.out.println(fun2());当调用fun2()时,发现子类覆写了fun1(),所以调用子类方式
作者: 经济    时间: 2015-6-4 11:13
  a.fun1();    -------原理同上,此题主要是考查你对多态的了解
作者: 2666fff    时间: 2015-6-4 12:05
本帖最后由 2666fff 于 2015-6-4 12:07 编辑

a.fun1();//这里又是怎么使用子类的呢?它的原理和运行方式,请详细解答????

这个是因为B继承A是A的子类,父类的引用指向了子类的对象。
根据多态:a这个引用能调用的方法必须是b(子类)类里重写了a(父类)的方法,所以打印出456 而不是A的123
所以B里面你再加一个
                void fun3() {
                         printf(11);
                 }
a是不能调用的。



作者: rexih    时间: 2015-6-4 12:45
想要理解多态光看毕老师的视频不够的,毕老师视频里面只告诉你结果

实际上,对于类中的方法,非静态的方法都有一个隐式参数this,而非静态方法则没有。

静态方法和域,通过ClassName.func(),ClassName.val就可以直接调用,静态域也称为类域。他们随着类加载进内存就存在了,先于实例对象而生。
我们知道this指向的是实例对象本身,而静态域先于实例对象生成,肯定是不会有this的。

那么如前所述,非静态方法在调用时,this是作为隐式参数的,比如a.func(),实际上func不是无参数,而是有一个this指向a的参数。
那么在调用多态方法时候,this指向的是哪个,调用的就是哪个方法,this指向的是内存中的实例对象,所以多态在调用非静态方法时,调用的是对象实际类型的方法。

而静态方法没有this隐式参数,则调用的是声明的类型的方法。
  B b = new B();
  b.fun1();//这里为嘛调用子类方式
b指向的是new B()创建的B类实例,所以b.fun1()调用的是B类的fun1。

A a = b;
a.fun1();//这里又是怎么使用子类的呢?它的原理和运行方式,请详细解答????
a是声明为A类型的对象变量,a的值是b的值的引用,而b指向的是new B()创建的B类实例。
所以A a是声明为父类,但是指向子类实例对象的。
所以如前所述,a在调用fun1()时,fun1()的隐式参数this,所指向的对象是new B()创建的B类实例,所以fun1()会调用的是B类的fun1()。





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2