我对动态绑定和静态绑定感到困惑。我已经读过在编译时确定对象的类型称为静态绑定,在运行时确定它称为动态绑定。
以下代码中会发生什么:
静态绑定还是动态绑定?
这显示了什么样的多态性?
class Animal
{
void eat()
{
System.out.println("Animal is eating");
}
}
class Dog extends Animal
{
void eat()
{
System.out.println("Dog is eating");
}
}
public static void main(String args[])
{
Animal a=new Animal();
a.eat();
}
答案 0 :(得分:66)
您的示例是动态绑定,因为在运行时确定a
的类型是什么,并调用适当的方法。
现在假设您还有以下两种方法:
public static void callEat(Animal animal) {
System.out.println("Animal is eating");
}
public static void callEat(Dog dog) {
System.out.println("Dog is eating");
}
即使您将main
更改为
public static void main(String args[])
{
Animal a = new Dog();
callEat(a);
}
这将打印Animal is eating
,因为对callEat
的调用使用静态绑定,编译器只知道a
的类型为Animal
}。
答案 1 :(得分:22)
如果你做了类似这样的事情,这实际上取决于重载和覆盖:
public class Animal{}
public class Dog extends Animal{}
public class AnimalActivity{
public void eat(Animal a){
System.out.println("Animal is eating");
}
public void eat(Dog d){
System.out.println("Dog is eating");
}
}
然后在主要课程中:
public static void main(String args[])
{
Animal a=new Animal();
Animal d=new Dog();
AnimalActivity aa=new AnimalActivity();
aa.eat(a);
aa.eat(d);
}
两种情况的结果将是:Animal is eating
但是让它扭曲一下,让我们来看看:
public class Animal{
public void eat(){
System.out.println("Animal is eating");
}
}
然后:
public class Dog extends Animal{
public void eat(){
System.out.println("Dog is eating");
}
}
然后在主要课程中:
public static void main(String args[]){
Animal d=new Dog();
Animal a=new Animal();
a.eat();
d.eat();
}
现在的结果应该是:
Animal is eating
Dog is eating
这是因为在编译时重载绑定“静态绑定” 而覆盖在运行时绑定“动态绑定”
答案 2 :(得分:1)
您当前的代码将输出
Animal is eating
但是,在您的主类中,如果您创建了Dog
类型的对象并将其分配给Animal
,那么由于动态绑定,您的输出将为Dog is eating
。
public static void main(String args[])
{
Animal a = new Dog(); // An object of Dog is assigned to Animal
a.eat(); // Dynamically determines which eat() method to call
}
即使a
被声明为Animal
,它也指向Dog
类型的对象。因此,在运行时,确定对象类型并调用适当的eat()
方法。
考虑它的一种方法是,method overloading
是静态绑定的,method overriding
是动态绑定的。
答案 3 :(得分:1)
对于非静态函数,只要函数是非虚函数,即使用final
关键字和/或函数为private
,就使用静态绑定。 final
表示无法更改函数,private
关键字表示它只有类范围。否则,使用动态绑定。
对于静态函数,始终使用静态绑定。如果传入类型A
,它将运行A
的方法,无论A
引用的位置如何。
答案 4 :(得分:0)
案例1:
Animal a =new Animal();
a.eat();
案例2:
Animal a=new Dog();
a.eat();
这里两者都是动态绑定,因为在编译期间确定了对象的类型,但是在运行时基于实例,分配了相应的eat方法的对象将由JVM动态绑定。
在第一种情况下,动物类吃方法被调用,而在第二种情况下,狗类吃被称为动物对象被指定为Dog实例。狗的实例也是动物的实例。也就是说你可以把它当作“是”关系,狗是动物。所以这里对象的类型在运行时被确定为狗,JVM动态地绑定狗类的eat方法。
检查此链接
http://www.javatpoint.com/static-binding-and-dynamic-binding
http://www.coderanch.com/t/386124/java/java/Static-Binding-Dynamic-Binding
答案 5 :(得分:0)
检查一下
employee类具有抽象earning()
函数,每个类都有不同的toString()
实现
Employee[] employees = new Employee[4];
// initialize array with Employees
employees[0] = new SalariedEmployee();
employees[1] = new HourlyEmployee();
employees[2] = new CommissionEmployee();
employees[3] = new BasePlusCommissionEmployee();
for (Employee currentEmployee : employees){
System.out.println(currentEmployee); // invokes toString
System.out.printf("earned $%,.2f%n", currentEmployee.earnings());
}
方法toString
和earnings
的所有调用均在execution time
根据currentEmployee引用的type of the object
解决,
此过程称为dynamic binding
或late binding