Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从基类方法调用基类重写函数_Java_Oop_Theory_Overloading - Fatal编程技术网

Java 从基类方法调用基类重写函数

Java 从基类方法调用基类重写函数,java,oop,theory,overloading,Java,Oop,Theory,Overloading,我希望这段代码能够输出: public class A { public void f1(String str) { System.out.println("A.f1(String)"); this.f1(1, str); } public void f1(int i, String str) { System.out.println("A.f1(int, String)"); } } public clas

我希望这段代码能够输出:

public class A {
    public void f1(String str) {
        System.out.println("A.f1(String)");
        this.f1(1, str);
    }

    public void f1(int i, String str) {
        System.out.println("A.f1(int, String)");
    }
}



public class B extends A {
    @Override
    public void f1(String str) {
        System.out.println("B.f1(String)");
        super.f1(str);
    }

    @Override
    public void f1(int i, String str) {
        System.out.println("B.f1(int, String)");
        super.f1(i, str);
    }
}


public class Main {
    public static void main(String[] args) {
        B b = new B();
        b.f1("Hello");
    }
}
但我得到了:

B.f1(String)
A.f1(String)
A.f1(int, String)
我知道在B的上下文中,A.f1(字符串)中的“this”是B的实例。 我是否可以选择执行链new B1().f1(字符串)->(A的)f1(字符串)->(A的)f1(int,字符串)

这是一个理论上的问题,实际上,解决方案显然是实现一个f1(String)和f1(int,String)都将调用的私有函数

谢谢你,

Maxim.

Java中重写的方法是动态绑定的。i、 e.对象的实际实例的类型决定了将调用什么
final
方法(不能重写)和
private
方法(不能继承)是静态绑定的


在C++中,为了对比,您必须明确地使函数 Virtual获得相同的行为。java中的< /P>

重写方法是动态绑定的。i、 e.对象的实际实例的类型决定了将调用什么

final
方法(不能重写)和
private
方法(不能继承)是静态绑定的


在C++中,对比度,你必须明确地使函数 Virtual得到相同的行为。

< P>恐怕是不可能的,但是有一个简单的解决办法:

B.f1(String)
A.f1(String)
B.f1(int, String)
A.f1(int, String)

恐怕这是不可能的,但有一个简单的解决办法:

B.f1(String)
A.f1(String)
B.f1(int, String)
A.f1(int, String)
不幸的是,没有

我相信您一定知道,但为了完整性,我将明确声明-只有两个关键字可以控制方法调用:

  • this-
    this.method()
    -查找从调用实例的类开始的方法(实例的“top”虚拟表-隐含默认值)
  • super-
    super.method()
    -查找从定义调用方法的类的父类开始的方法(调用类的“父虚拟表”,但这种方式更简单-谢谢@maaartinus)
我可以想象另一个关键字(如current?)会按照您的描述进行操作:

  • current-
    current.method()
    -查找从定义调用方法的类开始的方法
但是Java没有这样一个关键字(还没有?)。

不幸的是,没有

我相信您一定知道,但为了完整性,我将明确声明-只有两个关键字可以控制方法调用:

  • this-
    this.method()
    -查找从调用实例的类开始的方法(实例的“top”虚拟表-隐含默认值)
  • super-
    super.method()
    -查找从定义调用方法的类的父类开始的方法(调用类的“父虚拟表”,但这种方式更简单-谢谢@maaartinus)
我可以想象另一个关键字(如current?)会按照您的描述进行操作:

  • current-
    current.method()
    -查找从定义调用方法的类开始的方法

但是Java没有这样的关键字(还没有?)。

我尝试使用反射(为a的f1(int,String)获取一个方法对象并调用它),但没有成功。Sun博客中的[blog entry][1]指出,这在Java中是不可能的。[1] :我尝试使用反射(为a的f1(int,String)获取一个方法对象并调用它),但没有成功。Sun博客中的[blog entry][1]指出,这在Java中是不可能的。[1] :AFAIK,
super.method()。好吧,它是用invokespecial编译的。@maaartinus-谢谢-啊,我喜欢每天学习新东西。因此,没有
invokevirtualstartingfromparent
指令-
invokespecial
用于
super
调用,而
invokespecial
使用编译时绑定。因此,在调用
super
时,我们对类型有足够的了解,可以对目标方法进行编译时解析。如果该方法没有在直接超类中实现,那么我假设仍然需要向上搜索层次结构。最终结果实际上是一样的吗?我认为在运行时没有任何查找,即使在这种情况下也没有。IIUIC,
super
实际上是指拥有它的始祖。编译器必须知道整个层次结构,以便在类文件中写入正确的祖先。如果该方法不存在(这只能通过使用另一个类文件的技巧来实现),将抛出一个NoSuchMethodError。@maartinus-同意,该方法始终在编译时解决。我的意思是在编译时“搜索的等价物……仍然是必需的”,因此最终结果是相同的——找到并调用层次结构上最近的方法。AFAIK,
super.method()
不会从父级的VT开始。根本没有VT查找,它的工作方式类似于调用私有方法。好吧,它是用invokespecial编译的。@maaartinus-谢谢-啊,我喜欢每天学习新东西。因此,没有
invokevirtualstartingfromparent
指令-
invokespecial
用于
super
调用,而
invokespecial
使用编译时绑定。因此,在调用
super
时,我们对类型有足够的了解,可以对目标方法进行编译时解析。如果该方法没有在直接超类中实现,那么我假设仍然需要向上搜索层次结构。最终结果实际上是一样的吗?我认为在运行时没有任何查找,即使在这种情况下也没有。IIUIC,
super
实际上是指拥有它的始祖。T
package main;

public class A {
public void f1(String str) {
    System.out.println("A.f1(String)");
    if (this instanceof B)
        new A().f1(1, str);
    else
        this.f1(1, str);
}

public void f1(int i, String str) {
    System.out.println("A.f1(int, String)");
}

}

class B extends A {
@Override
public void f1(String str) {
    System.out.println("B.f1(String)");
    super.f1(str);
}

@Override
public void f1(int i, String str) {
    System.out.println("B.f1(int, String)");
    super.f1(i, str);
}

public static void main(String[] args) {
A a = new B();
    a.f1("Hello");
}
}