码迷,mamicode.com
首页 > 编程语言 > 详细

java的动态绑定与双分派(规避instanceof)

时间:2014-06-25 23:13:22      阅读:293      评论:0      收藏:0      [点我收藏+]

标签:style   class   blog   code   java   tar   

1. 动态绑定的概念

    指程执行期间(而不是在编译期间)判断所引用对象的实际类型,根据其实际的类型调用其相应的方法 .

    例如: 

package org.demo.clone.demo;

public class DynamicBound {
    public static void main(String[] args) {
          Person person = new Man() ;
          person.say() ;
    }
}


class Person{
    public void say(){} ;
}


class Man extends Person{
    public void say(){
        System.out.println("Hey Man");
    }
}

 

结果:

 

Hey Man

 

    调用的是Person对象中的say方法 但是实际执行的是Man中的方法,这就是动态绑定。 在java语言中,继承中的覆盖就是是动态绑定的,当我们用父类引用实例化子类时,会根据引用的实际类型调用相应的方法

 

2. 静态绑定 

    静态绑定就是指在编译期就已经确定执行哪一个方法。方法的重载(方法名相同而参数不同)就是静态绑定的,重载时,执行哪一个方法在编译期就已经确定下来

package org.demo.demo;

public class StaticBound {
    public static void main(String[] args) {
        OutputName out = new OutputName() ;
        Person p = new Person() ;
        Person man = new Man() ;
        Person woman = new Woman() ;
        out.print(p) ;
        out.print(man) ;
        out.print(woman) ;
    }
}


class Person{
}

class Man extends Person{
    
}
class Woman extends Person{
    
}


class OutputName{
    void print(Person p){
        System.out.println("person");
    }
    void print(Man m){
        System.out.println("man");
    }
    void print(Woman w){
        System.out.println("woman");
    }
}

 

 

执行的结果: 

person
person
person

不管在运行的时候传入的实际类型是什么,它永远都只会执行 void print(Person p)这个方法,即 : 重载是静态绑定的

  如果希望使用重载的时候,程序能够根据传入参数的实际类型动态地调用相应的方法,也就是说,我们希望java的重载是动态的,而不是静态的。

但是由于java的重载不是动态绑定,只能通过程序来人为判断,我们一般会使用instanceof操作符来进行类型的判断  代码如下: 

package org.demo.demo;

public class StaticBound {
    public static void main(String[] args) {
        OutputName out = new OutputName() ;
        Person p = new Person() ;
        Person man = new Man() ;
        Person woman = new Woman() ;
        out.print(p) ;
        out.print(man) ;
        out.print(woman) ;
    }
}


class Person{
}

class Man extends Person{
    
}
class Woman extends Person{
    
}


class OutputName{
    void print(Person p){
        if(p instanceof Man) print((Man)p);
        else if (p instanceof Woman) print((Woman)p);
        else  System.out.println("person");
    }
    void print(Man m){
        System.out.println("man");
    }
    void print(Woman w){
        System.out.println("woman");
    }
}

 

 

结果: 

person
man
woman

 

 

      这种实现方式有一个明显的缺点,它是伪动态的,仍然需要我们来通过程序来判断类型。假如有100个子类的话,还是这样来实现显然是不合适的

必须通过其他更好的方式实现才行,我们可以使用双分派方式来实现动态绑定

 

3. 使用双分派实现动态绑定

    什么是双分派: 

   

package org.demo.demo;
/**
 * 双分派
 */
public class DoubleAssign {
    public static void main(String[] args) {
        A a = new A() ;
        a.method02(new B()) ;
    }
    
}



class A {
    public void method01(){
        System.out.println("\t method01");
    }
    public void method02(B  b ){
        b.classMethod01(this) ;
    }
}


class B{
    public void classMethod01(A a ){
        System.out.println("------classMethod01 start----- ");
        a.method01();
        System.out.println("------classMethod01 end----- ");
    }
}

 

 

通过双分派实现动态绑定

package org.demo.demo.foo;
/**
 * 通过双分派实现动态绑定
 */
public class DoubleAssignForDynamicBound {
    public static void main(String[] args) {
        OutputName out = new OutputName() ;
        Person p = new Person() ;
        Person man = new Man() ;
        Person woman = new Woman() ;
        p.accept(out) ;
        man.accept(out) ;
        woman.accept(out) ;
    }
}


class Person{
    public void accept(OutputName out) {
        out.print(this) ;
    }
}

class Man extends Person{
    public void accept(OutputName out) {
        out.print(this) ;
    }
}
class Woman extends Person{
    public void accept(OutputName out) {
        out.print(this) ;
    }
}


class OutputName{
    void print(Person p){
        System.out.println("person");
    }
    void print(Man m){
        System.out.println("man");
    }
    void print(Woman w){
        System.out.println("woman");
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

java的动态绑定与双分派(规避instanceof),布布扣,bubuko.com

java的动态绑定与双分派(规避instanceof)

标签:style   class   blog   code   java   tar   

原文地址:http://www.cnblogs.com/liaokailin/p/3804437.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!