这是我的代码,我无法推断为什么输出会像那样。如果有人能解释请。
import java.io.*;
class b {
void m(b a){
System.out.println(" b");
}
}
class bcd extends b {
void m(bcd a){
System.out.println("bcd");
}
}
class cde extends bcd {
void m(cde a){
System.out.println("cde");
}
}
public class ABC{
public static void main(String[] args){
b ob1= new cde();
cde ob2=new cde();
ob1.m(ob2);
}
}
答案 0 :(得分:1)
在您的示例中,将调用b类中的方法。我想你想显示重写或重载的例子,但这不是重写而不是重载。
用于覆盖使用后期绑定。在这种情况下,知道方法签名后,虚拟机会分析调用此方法的实例化(实际)类型的对象,以准确确定要调用的方法定义的类。 对于重载使用早期绑定。在这种情况下,编译器检查正式类型的对象
很好的例子解释了覆盖或重载:
public class Test{
public static class Parent{
public void test(){
System.out.println("parent class");
}
}
public static class Child extends Parent{
public void test(){
System.out.println("child class");
}
}
public static class Tester{
public void test(Parent obj){
System.out.println("Parent method");
obj.test();
}
public void test(Child obj){
System.out.println("Child method");
obj.test();
}
}
public static void main(String[] args){
Parent obj = new Child();
Tester t = new Tester();
t.test(obj);
}
}
结果执行:
父方法
儿童班
修改强> 1)编译器不查看类型参数。它根据调用它的实际类型对象确定调用的方法:对于你的例子,这是b类,对于我的例子,这是Tester类.2)如果我们在一个具有相同名称的类中有两个方法,但是方法中的不同类型参数(重载),然后java虚拟机查看类型参数(在我的例子中如何:两个方法具有相同的名称,但传输类Parent的对象和使用Parent参数的调用方法)
在你的例子中,如果是这样的话:
class B {
void m(B a){
System.out.println(" b");
}
void m(Cde a){
System.out.println("cde");
}
}
public class ABC{
public static void main(String[] args){
B ob1= new Cde();
Cde ob2=new Cde();
ob1.m(ob2);
}
}
这是重载示例,将调用void m(cde a)
<强> EDIT2:强> 是的,你的ob1对象是实例cde,但java虚拟机只检查实例化(真实)类型的对象,以防覆盖(当两个类中的方法签名相同时)。所以,你需要记住两个覆盖和重载的东西,在其他情况下编译器查看正式类型引用,在你的例子中这是b。
但最重要的是有趣的事情。
来自http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.5
如果相反,则返回类型可能会因为相互覆盖的方法而异 返回类型是引用类型。的概念 return-type-substitutability支持协变返回,即 将返回类型专门化为子类型。
A method declaration d1 with return type R1 is return-type-substitutable for another method d2 with return type R2,
当且仅当满足以下条件时:
If R1 is void then R2 is void. If R1 is a primitive type, then R2 is identical to R1. If R1 is a reference type then: R1 is either a subtype of R2 or R1 can be converted to a subtype of R2 by unchecked conversion (§5.1.9), or R1 = |R2|
如果您的代码具有不同的返回类型,但参数相同,那么它也将是示例覆盖:
class Bcd extends B {
@Override
Bcd m(Cde a) {
System.out.println("bcd");
return a;
}
}
class Cde extends Bcd {
@Override
Cde m(Cde a) {
System.out.println("cde");
return a;
}
}
class B {
B m(Cde a) {
System.out.println("b");
return a;
}
}
class Test {
public static void main(String[] args) {
final B ob1 = new Cde();
final Cde ob2 = new Cde();
ob1.m(ob2);
}
}
结果:
CDE
因为这也是最重要的。
答案 1 :(得分:0)
当您调用ob1.m(ob2);
时,将调用类b的方法。
类
class bcd extends b {
void m(bcd a) {
System.out.println("bcd");
}
}
class cde extends bcd {
void m(cde a) {
System.out.println("cde");
}
}
是重载方法而不是覆盖方法。