方法调用是如何发生的?
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)
)
如果您的 obj
是 Derived
类型,那么这两种情况都有效:
obj.method();
// 将从 Derived class 调用此方法
obj.method(1);
// 将从 Base class 调用此方法
Base obj=new Derived();
在上面的语句中,引用部分指向类型Base
。这就是编译器识别要考虑的 class 的方式。但是您的代码会产生错误。先解释一下上面语句的结构再解释为什么会报错
上述语句的结构:
- 声明-参考部分为
Base obj
.
实例化:new关键字是一个Java运算符,在内存中创建object/allocatesspace
初始化:new 运算符之后调用构造函数,初始化新对象。
由于 Derived
是 Base
的子 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 的对象
我是 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)
)
如果您的 obj
是 Derived
类型,那么这两种情况都有效:
obj.method();
// 将从 Derived class 调用此方法
obj.method(1);
// 将从 Base class 调用此方法
Base obj=new Derived();
在上面的语句中,引用部分指向类型Base
。这就是编译器识别要考虑的 class 的方式。但是您的代码会产生错误。先解释一下上面语句的结构再解释为什么会报错
上述语句的结构:
- 声明-参考部分为
Base obj
. 实例化:new关键字是一个Java运算符,在内存中创建object/allocatesspace
初始化:new 运算符之后调用构造函数,初始化新对象。
由于 Derived
是 Base
的子 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 的对象