0

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

__编辑__

根据我从每个人那里收到的答案,我有代码:

在这里,我将我的Derived对象 ( obj) 类型转换为Basetype 然后调用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");
    }
}

我得到的输出是:“派生”。

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

typecast 是否适用于 child->parent 转换或者它在这里没有效果?

4

3 回答 3

1

Base obj=new Derived();

在上面的语句中,引用部分指向 type Base。这就是编译器如何识别要考虑的类。但是您的代码会产生错误。在解释为什么会显示错误之前,让我先解释一下上述语句的结构。

上述语句的结构:

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

  3. 初始化:new 操作符之后是对构造函数的调用,该构造函数初始化新对象。

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

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

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

你注意到了吗?

  • 我已将引用替换为 type Derived

为什么这行得通?

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

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

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

上面的语句意味着以下代码将起作用:

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

您一定想知道 - 即使method()inDerived不需要参数,这段代码是如何工作的。事实上,Derived没有method(int a).

嗯,这个问题的答案就是我上面提到的惊人事实。

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

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

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

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

继承如何运作?

  • 当你obj.method(5)在上面的代码中调用时,JVM 首先会在Derived. 如果它没有找到任何被覆盖的方法,它会向上移动inheritance hierarchy chain到超类并查找相同的方法。但相反的情况并非如此。
于 2016-02-14T13:22:34.587 回答
0

编译器如何知道要从哪个类调用哪个方法?

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


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

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


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


如果你obj是 type Derived,那么这两种情况都可以工作:

  • obj.method();// 将从 Derived 类调用此方法
  • obj.method(1);// 将从基类调用此方法
于 2016-02-14T13:19:46.910 回答
0

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

于 2016-02-14T17:48:49.687 回答