静态绑定和动态绑定

时间:2013-05-20 10:33:05

标签: java oop polymorphism dynamic-binding static-binding

我对动态绑定和静态绑定感到困惑。我已经读过在编译时确定对象的类型称为静态绑定,在运行时确定它称为动态绑定。

以下代码中会发生什么:

静态绑定还是动态绑定?
这显示了什么样的多态性?

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();
}

6 个答案:

答案 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());
}

方法toStringearnings的所有调用均在execution time根据currentEmployee引用的type of the object解决,

此过程称为dynamic bindinglate binding

参考:Java™ How To Program (Early Objects), Tenth Edition