方法调用是如何发生的?

How does method invoking takes place?

我是 Java 编程和学习多态性的新手。

__EDIT__

根据大家的回答,我有代码:

在这里,我将我的 Derived 对象 (obj) 类型转换为 Base 类型,然后调用 method().

public class Tester {
    public static void main(String[] args) {
        Base obj=(Base)new Derived();
        obj.method();
    }   
}

class Base{
    public void method(){
        System.out.println("In Base");
    }
}

class Derived extends Base{
    public void method(){
        System.out.println("In Derived");
    }
}

我得到的输出是:"In Derived"。

所以在类型转换之后,我的对象应该变成 Base 类型引用的 Base 类型。 但它没有发生?为什么?

typecast 对 child->parent 转换起作用还是在这里不起作用?

how does compiler comes to know which method is to be called & too from which class?

编译器在对象(本例obj)的class(本例Base)中搜索方法。如果在 class 中没有找到该方法,那么它将在超级 class 中查找方法(在本例中为 Object)。如果仍未找到,它会标记错误。


Is it that compiler checks the reference type class & if method to be invoked is not present in reference type class it gives error??

是的。但是,如前所述,如果在那个 class 中找不到该方法,那么它会在超级 class 中查找该方法(在本例中为 Object)。如果仍未找到,它会标记错误。


您的 obj.method() 将失败,因为 Base 没有签名为 method() 的方法(它有 method(int)


如果您的 objDerived 类型,那么这两种情况都有效:

  • obj.method(); // 将从 Derived class
  • 调用此方法
  • obj.method(1); // 将从 Base class
  • 调用此方法

Base obj=new Derived();

在上面的语句中,引用部分指向类型Base。这就是编译器识别要考虑的 class 的方式。但是您的代码会产生错误。先解释一下上面语句的结构再解释为什么会报错

上述语句的结构:

  1. 声明-参考部分为Base obj.
  2. 实例化:new关键字是一个Java运算符,在内存中创建object/allocatesspace

  3. 初始化:new 运算符之后调用构造函数,初始化新对象。

由于 DerivedBase 的子 class,您可以调用 Derived class 中的构造函数。这就是继承和多态性的工作原理。

好了,现在让我们回到错误的部分。 您代码中的 obj.method() 正在 Base class 中寻找函数 method()Base class 中的 method(int a) 函数需要要传递的整数类型的参数。因此,要使代码正常运行,调用语句必须类似于 obj.method(5)。此语句之所以有效,是因为调用语句实际上是将 5 传递给函数。

您的代码有一个简单的修复方法: Derived obj=new Derived();

你注意到了吗?

  • 我已将引用替换为类型 Derived

为什么这样行得通?

  • 因为 Derived class 中有 method() 函数,它不需要整数参数。

Java中还有一个关于继承的惊人事实:

Everything possessed by a super-class is also possessed by the sub-class but the reverse is not true. And yes, the sub-class has the right to redefine any method/function it has inherited from super-class.

上面的语句意味着下面的代码可以工作:

Derived obj=new Derived();
obj.method(5);

您一定想知道 - 即使 Derived 中的 method() 不需要参数,为什么这段代码仍然有效。其实Derived没有method(int a).

Well, the answer to this is the amazing fact I have mentioned above.

是的,method(int a) 也属于 Derived,因为它是 Base 的子 class。

但是下面提到的代码是如何工作的?

Derived obj=new Derived();
obj.method(5);

很简单,JVM 在 class Derived 中查找 method(int a) 并找到函数,因为 Derived 继承了 Base 的函数 class。 也要记住这一点,sub-class 也有权限覆盖 superclass 中的方法。这意味着您可以在 class Derived 中添加 method(int a) 函数,它会覆盖从 Base.

继承的原始方法

继承是如何工作的?

  • 当你在上面的代码中调用obj.method(5)时,JVM首先会在Derived中查找相同类型的任何被覆盖的方法。如果它没有找到任何被覆盖的方法,它会在 inheritance hierarchy chain 中向上移动到超级 class 并寻找相同的方法。但事实并非如此。

当不同的 classes 中有相同的方法名称时,编译器通过以下方式知道: 1-如果你传递任何参数,那么你传递的参数类型将告诉编译器要调用哪个方法 2-如果有两个 classes ,则创建要为其调用方法

的那个 class 的对象