为了说清楚,我已经详细阐述了我的问题。
我这里有这个代码,它使用覆盖的概念来阐述动态绑定。
以下是代码:
class Test {
public static void main(String [] args)
{
B b = new A();
b.p(10); // 10.0
b.p(10.0); // 10.0
}
}
class B
{
public void p(double i)
{
print(i*2);
}
}
class A extends B
{
public void p(double i)
{
print(i);
}
}
现在,解释说编译器无法确定在“编译时”期间调用哪个方法。正是在“运行时”,编译器知道需要调用的方法是子类方法,因为当我们覆盖时,我们正在查看实际类型。
与此代码对比:
class Test {
public static void main(String [] args)
{
B b = new A();
b.p(10); // 10.0
b.p(10.0); // 10.0
}
}
class B
{
public void p(double i)()
{
print(i*2);
}
}
class A extends B
{
public void p(int i)
{
print(i);
}
}
在此示例中,编译器可以识别在编译期间调用哪个方法。如果在前面的例子中无法识别int,那么编译器如何在此示例中识别? 问题:
术语“编译时间”和“运行时间”究竟是什么意思?编译器在编译期间如何识别需要调用的函数是子类函数?
答案 0 :(得分:5)
考虑以下(伪)代码:
B b = Rand() > 0.5?new A() : new B();
b.p(10);
编译器无法知道在运行时调用哪个。
答案 1 :(得分:3)
这是非常自我解释的
编译时和运行时指的是一段时间
编译时间是编译器构建项目的时间。
运行时是项目运行的时间。
我假设您在代码运行之前询问为什么您的代码不知道B
是A
。在以下部分中:
B b = new A();
b.p(10); // 20.0
b.p(10.0); // 20.0
原因是编译器没有评估代码中的每个可能路径来检查那些东西。当你看到稍微复杂的实现时,这更容易理解。
B b = new A();
if(...)
{
...
b = new B();
}
b.p(10); // 20.0
b.p(10.0); // 20.0
它只知道代码实际执行时b
是什么。
答案 2 :(得分:2)
运行时间表示“程序运行时”。
编译时间表示“编译程序时 ”。
某些事情只在运行时才知道。
一个例子是用户输入。
编译器无法预测用户在运行时输入的内容。
答案 3 :(得分:1)
术语“编译时间”和“运行时间”究竟是什么意思?
编译时间是将代码编译为可执行代码(字节代码)的时间。这意味着,所有文件都是链接的(由import
表达式包含),并且字节代码,即指令序列被创建。
运行时是指CPU运行已编译的代码 - 字节代码。
编译器在编译期间如何识别需要调用的函数是子类函数?
实际上确实如此。如果它无法识别,那么它将无法编译,因为编译必须知道明确知道要调用的方法,以便为运行时准备代码。您提供的代码有效,并且将执行类p()
中的A
方法。
答案 4 :(得分:1)
考虑:
List x = getsSomeList();
x
可以是List
接口的任何实现。
如果您致电x.add(foo)
,则在执行之前将无法知道正确的add
方法,并且有一个实际的实施方式可以调用add
。
答案 5 :(得分:0)
当您使用多态时,编译器无法知道哪个方法调用,因为您可以使用相同方法的许多实现...因为它只能在运行时确定。
答案 6 :(得分:0)
“编译时”和“运行时”之间的区别在于编译期间,JVM会检查程序员编写的程序中的语法,特定Java和其他错误。运行时是在运行应用程序期间检查的内容。
您可能在语法上正确,但在运行时有很多错误。例子: 拼错的话 程序中的逻辑 它的运行方式 事情如何处理动画等
它依赖
答案 7 :(得分:0)
由于多态性,编译器无法知道调用哪个方法,如上所述that the compiler cannot determine which method to call during"compile time"
这意味着由于函数的多种形式可用,编译器决定在编译应用程序时它将调用哪个函数版本,所以相反它决定在程序执行运行时调用哪个方法。
如果extended/derived
类overloads
你试图调用它的函数/方法从derived class
调用方法,如果方法没有在派生类中重载,那么它将从base class
调用该方法。这就是动态绑定在面向OOP的语言中的工作原理。
答案 8 :(得分:-2)
看起来您提供的示例不正确。
在两次调用中输出均为10.0,而不是您所说的20.0。