史帅锅
现有代码
class A
{
    A()//A的构造函数
    {
        f(); // 调用f方法
    }
   
    protected void f()// 受保护的 f 方法
    {
        System.out.printf("这是 A 类的 f 方法!\n");
    }
}

class B extends A
{
    B()//B的构造函数
    {
        super();//调用父类(class A)的构造方法!
    }
    protected void f()//重写父类的 f 方法!
    {
        System.out.printf("这经 B 类重写的的 f 方法!\n");
    }
}

class Main
{
    public static void main (String [] args)
    {
        B bb = new B();// new出一个B
    }
}
/*
代码所见:
   
类 A 的构造函数会调用f方法。
    A 的protected void f方法被子类 B 重写。
    (子类) B 的构造方法 会调用(父类) A 的构造方法。

问题
    若该程序执行,调用的 f 方法是谁的? 为什么?
*/

a837507757
应该是子类的方法。我会C++,不会java,应该差不多。

andylizi
这个问题我居然没法给出肯定的答案,,看来面向对象有些地方还是没学好。。
我猜输出的是
这经 B 类重写的的 f 方法!
,至于为什么嘛。。。1+1为什么等于2啊?


话说你为何要用printf,C系里带来的习惯么。

云闪
调用的是B类重写的方法,因为你new的是B的对象,所以会调用B重写的方法_(:зゝ∠)_
如果我没记错的话,解释应该是这样

A的构造函数里对f()的调用,会被编译成invokevirtual #A.f() ()V
而invokevirtual会根据对象的实际类型去调用方法(这好像叫做动态绑定?反正这就是多态的实现机制0.0),这里的实际类型是B,所以调用的是B类重写的方法

dogeop
所以你都写出实例代码了为什么不运行一下来看看呢.

史帅锅
dogeop 发表于 2016-7-27 10:31
所以你都写出实例代码了为什么不运行一下来看看呢.

这经 B 类重写的的 f 方法!

听起来是极棒的。但为什么呢?

ak1115284886
应该是b的f方法吧 这应该算是个简单的覆写   而且这里的protect实际上继承后没有什么实际意义了


a11889
Java中,使用的是后期绑定(动态绑定)的方法调用绑定,也就是说在运行时根据对象的类型进行绑定。非final非static方法将会被自动动态绑定。
因此,你在构造器中调用并不知道是父类还是子类的方法的时候,动态绑定会调用子类的方法。
如果要究其原理,我想,楼上分析JVM字节码的仁兄已经说得很清楚了。

以上部分内容摘自《Java编程思想(第4版)》第8章多态。如果想了解Java的多态机制我想百度可以更好地帮到你。

phpsyser
B的
要调用A的F()方法super.f();
剩下的自己领悟
import java.io.*;
class Main
{
    public static void main (String [] args)
    {
        B bb = new B();// new出一个B
      // System.out.println(111);
    }
}

class A
{
    A()//A的构造函数
    {
        System.out.printf("这经aaaa 方法!\n");
        f(); // 调用f方法
    }
   
    protected void f()// 受保护的 f 方法
    {
        System.out.println("这是 A 类的 f 方法!\n");
    }
}


class B extends A
{
    B()//B的构造函数
    {
        super.f();//调用父类(class A)的构造方法!
    }
    protected void f()//重写父类的 f 方法!
    {
        System.out.printf("这经 B 类重写的的 f 方法!\n");
    }
}

第一页 上一页 下一页 最后一页