静态绑定和动态绑定



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

下面的代码发生了什么:

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

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

您的示例是动态绑定,因为在运行时确定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的调用使用了静态绑定,编译器只知道aAnimal类型。

这实际上取决于重载重写如果你这样做:

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

这是因为重载在编译时绑定了"静态绑定"当在运行时重写绑定时"动态绑定"

您的当前代码将输出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是动态绑定的。

对于非静态函数,只要函数是非虚拟的,即final关键字应用于它和/或函数是private,就使用静态绑定。final表示该函数不能更改,private关键字表示该函数只有类作用域。否则使用动态绑定。

对于静态函数,总是使用静态绑定。如果类型A被传入,它将运行A的方法,无论A引用到哪里。

Case 1:

Animal a =new Animal();
a.eat();

案例2:

Animal a=new Dog(); 
a.eat();

这里两者都是动态绑定,因为在编译时确定对象的类型,但在运行时基于实例,分配相应eat方法的对象将由JVM动态绑定。

在第一个例子中,动物类eat方法被调用,而在第二个例子中,狗类eat被调用,因为animal对象被分配了一个dog实例。狗的例子也是动物的例子。也就是说,你可以把它理解为""关系,狗是一种动物。因此,这里对象的类型在运行时被确定为dog, JVM动态绑定dog类的eat方法。

查看此链接

http://www.javatpoint.com/static-binding-and-dynamic-binding

http://www.coderanch.com/t/386124/java/java/Static-Binding-Dynamic-Binding

检查这个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™如何编程(早期对象),第十版

相关内容

  • 没有找到相关文章

最新更新