这是我的问题。我有一个带有抽象方法的超类。
public abstract class Base{
public abstract Boolean foo();
}
public class sub extends Base{
@Override
public Boolean foo(){
System.out.printLn("This is foo in the sub class!");
}
}
所以当我去主要并试试这段代码时
Base b = new sub();
b.foo();
我的屏幕上没有错误和消息显示。我的假设是编译器查看b对象并将其视为Base对象然后从Base对象转到foo并看到之后没有实现它从子进程中检出foo然后它看到方法foo是在那里实现,所以它显示了消息。我对吗?
答案 0 :(得分:1)
编译器没有那么多处理。在你的情况下 您已经创建了超类的引用变量,它将保存子类的对象。
现在,在调用方法时,它会根据您的对象类型直接调用子类中的方法。
我正在为您的评论添加代码供您参考。
1)只有方法声明的抽象类
public abstract class Base {
public abstract Boolean foo(); //method declaration
}
2)扩展父类的子类,必须实现方法,如果要将此类声明为具体类。
public class sub extends Base {
@Override
public Boolean foo() {
System.out.printLn("This is foo in the sub class!");
}
}
3)这里你已经声明了父类型的引用变量,它存储了你的子类的对象
Base b = new sub();
4)当这一行被执行时,编译器将检查,对象的类型是什么,并根据对象类型调用该方法。它不会调用引用变量类型的方法。
b.foo();
答案 1 :(得分:1)
编译器不会查看该方法是否由子类实现。它仅检查特定类类型引用调用的方法是否存在于类本身中。在运行时,它决定调用哪个方法意味着基类版本或子类版本。
所以你只是直到"我的假设是编译器查看b对象并将其视为Base对象然后它从Base"转到foo;言。