32

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

下面的代码会发生什么:

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

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

6 回答 6

69

您的示例是动态绑定,因为在运行时确定类型是什么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

于 2013-05-20T10:57:51.313 回答
23

This really depends on overloading and overriding if you did something like this:

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

then in the main class:

public static void main(String args[])
{
    Animal a=new Animal();
    Animal d=new Dog();
    AnimalActivity aa=new AnimalActivity();
    aa.eat(a);
    aa.eat(d);
}

the result in the two cases will be: Animal is eating

but lets twist it some, lets have this:

public class Animal{
    public void eat(){
        System.out.println("Animal is eating");
    }
}

then:

public class Dog extends Animal{
    public void eat(){
        System.out.println("Dog is eating");
    }
}

then in the main class:

public static void main(String args[]){
    Animal d=new Dog();
    Animal a=new Animal();
    a.eat();
    d.eat();
}

now the result should be:

Animal is eating
Dog is eating

this is because overloading binds at compile time "static binding" while overriding binds at run time "dynamic binding"

于 2013-05-20T11:46:52.553 回答
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动态绑定。

于 2013-05-20T10:42:36.483 回答
1

对于非静态函数,只要函数是非虚拟的,即final应用关键字和/或函数是 ,就使用静态绑定privatefinal意味着函数不能更改,private关键字意味着它只有类范围。否则,使用动态绑定。

对于静态函数,总是使用静态绑定。如果A传入了一个类型,它将运行A's 方法,而不管在哪里A引用。

于 2015-03-24T01:33:27.367 回答
0

情况1:

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

案例二:

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

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

在第一种情况下,调用动物类的eat方法,而在第二种情况下,调用狗类的方法,因为Animal对象被分配了一个Dog实例。Dog的实例也是animal的实例。那就是你可以把它当成狗是动物的“”关系。所以这里对象的类型在运行时被确定为狗,JVM动态绑定狗类的eat方法。

也检查此链接

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

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

于 2013-05-20T10:46:16.957 回答
0

检查这个员工类有抽象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());
}

根据currentEmployee 所指的 ,对方法toString和的所有调用earnings都在 处解析,execution timetype of the object

这个过程被称为dynamic bindinglate binding

参考:Java™ 如何编程(早期对象),第十版

于 2017-07-31T07:16:58.677 回答