方法调用是如何进行的?

时间:2016-02-14 13:12:07

标签: java casting polymorphism method-invocation

我是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");
    }
}

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

因此,在进行类型转换后,我的对象应该变为Base类型引用的Base类型。 但它没有发生?为什么呢?

类型转换是否适用于子级>父级转换,或者它在此处没有效果?

3 个答案:

答案 0 :(得分:1)

Base obj=new Derived();

在上面的陈述中,参考部分指向Base类型。这是编译器识别要考虑的类的方式。但是你的代码会产生错误。在解释为什么它会显示错误之前,让我解释一下上述陈述的结构。

以上陈述的结构:

  1. 声明 - 参考部分为Base obj
  2. 实例化:new关键字是一个Java运算符,用于在内存中创建对象/分配空间。

  3. 初始化:新运算符后面是对构造函数的调用,该构造函数初始化新对象。

  4. 由于DerivedBase的子类,因此您可以在Derived类中调用构造函数。这就是继承和多态的工作原理。

    好的,现在让我们回到错误部分。 代码中的obj.method()method()类中查找函数Base,但method(int a)类中的Base函数需要传递类型为integer的参数。因此,为了使代码工作,调用语句必须类似于obj.method(5)。此语句有效,因为调用语句实际上是将5传递给函数。

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

    你注意到了吗?

    • 我已将引用转发为Derived类型。

    为什么这样做?

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

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

      

    超级阶级所拥有的一切也被子级所拥有,但反之亦然。是的,子类有权重新定义它从超类继承的任何方法/函数。

    以上陈述意味着以下代码将起作用:

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

    你一定想知道 - 即使method()中的Derived不需要参数,这段代码也会如何运作。实际上,Derived没有method(int a)

      

    嗯,答案是我上面提到的令人惊讶的事实。

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

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

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

    很简单,JVM在类method(int a)中查找Derived,并且它找到了函数,因为Derived继承了Base类的函数。 记住这一点,子类也有权在超类中覆盖一个方法。这意味着您可以在类method(int a)中添加Derived函数,该函数会覆盖从Base继承的原始方法。

    继承如何运作?

    • 当您在上面的代码中调用obj.method(5)时,JVM首先在Derived中查找相同类型的任何重叠方法。如果它没有找到任何过度使用的方法,它会在inheritance hierarchy chain向上移动到超类并查找相同的方法。但反过来并非如此。

答案 1 :(得分:0)

  

编译器如何知道要调用哪个方法&哪个班级?

编译器搜索对象的类(在本例中为Base)中的方法(在本例中为obj)。如果在该类中找不到该方法,则它会在超类中查找该方法(在本例中为Object)。如果仍未找到,则标记错误。

  

是编译器检查引用类型类&如果在引用类型类中不存在要调用的方法,则它会给出错误??

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

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

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

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

答案 2 :(得分:0)

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

的该类的对象