我在一些计算机科学考试中看到了下一段,我希望我能在这里得到一个很好的解释,因为我用谷歌搜索了一个小时,找不到任何东西..
“当我们说Java语言虚方法调用时,我们的意思是在java应用程序中,执行的方法由运行时的对象类型决定”
这是什么意思?任何人都可以更好地解释它吗?
答案 0 :(得分:33)
这些行的作者使用了virtual
的c ++术语。
更好的术语是dynamic binding / dynamic dispatch。
这意味着,对象的动态type是“选择”将调用哪个方法,而不是静态类型。
例如:[伪代码]:
class A {
public void foo() { }
}
class B extends A {
public void foo() { }
}
调用时:
A obj = new B();
obj.foo();
B.foo()
将被调用,而不是A.foo()
,因为动态类型obj
为B
。
答案 1 :(得分:13)
我们的意思是在java应用程序中,执行的方法由运行时的对象类型
决定
interface Animal{
public void eat();
}
class Person implements Animal{
public void eat(){ System.out.println("Eating Food");}
}
class Eagle implements Animal{
public void eat(){ System.out.println("Eating Snake");}
}
主中的
Animal animal = new Person();
animal.eat(); //it will print eating food
animal = new Eagle();
animal.eat(); //it will print eating snake
答案 2 :(得分:4)
假设你有一个类Fruit,有两个子类Orange和Banana。假设Fruit有String getColor()
方法。
Orange可以覆盖getColor()
方法以返回“orange”。香蕉也是如此,它可以让它返回“黄色”。
当某些方法使用Fruit类型的对象并调用getColor()
方法时,如果Fruit的类型实际上是Banana,则将调用的方法为Banana.getColor()
。
private void printColor(Fruit f) {
System.out.println(f.getColor());
}
...
Fruit fruit1 = new Banana();
Fruit fruit2 = new Orange();
printColor(fruit1); // prints yellow
printColor(fruit2); // prints orange
答案 3 :(得分:1)
<强> Employee.java 强>
public class Employee
{
private String name;
private String address;
private int number;
public Employee(String name, String address, int number)
{
System.out.println("Constructing an Employee");
this.name = name;
this.address = address;
this.number = number;
}
public void mailCheck()
{
System.out.println("Mailing a check to " + this.name
+ " " + this.address);
}
}
<强> VirtualMethod.java 强>
class Salary extends Employee
{
private double salary; //Annual salary
public Salary(String name, String address, int number, double
salary)
{
super(name, address, number);
this.salary=salary;
}
public void mailCheck()
{
System.out.println("Within mailCheck of Salary class ");
System.out.println("Mailing check to "
+ " with salary " + salary);
}
}
public class VirtualMethod
{
public static void main(String [] args)
{
Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
System.out.println("Call mailCheck using Salary reference --");
s.mailCheck();
System.out.println("\n Call mailCheck using Employee reference--");
e.mailCheck();
}
}
<强>输出强>
Constructing an Employee
Constructing an Employee
Call mailCheck using Salary reference --
Within mailCheck of Salary class
Mailing check to with salary 3600.0
Call mailCheck using Employee reference--
Within mailCheck of Salary class
Mailing check to with salary 2400.0
<强>解释强>
这里,我们实例化两个Salary
个对象。一个使用Salary
引用s
,另一个使用Employee
引用e
。
在调用s.mailCheck()
时,编译器在编译时在mailCheck()
类中看到Salary
,并且JVM在运行时调用mailCheck()
类中的Salary
在mailCheck()
上调用e
是完全不同的,因为e
是Employee
引用。当编译器看到e.mailCheck()
时,编译器会在mailCheck()
类中看到Employee
方法。
这里,在编译时,编译器使用mailCheck()
中的Employee
来验证此语句。但是,在运行时,JVM会在mailCheck()
类中调用Salary
。