images.png

静态绑定

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

动态绑定

动态绑定实在运行时判断所引用对象的实际类型,根据其实际的参数类型调用其相应的方法(运行时多态) 。

双分派(double dispatch)

分派过程就是确定一个方法调用的过程,双分派就是见人说人话,见鬼说鬼话,将静态绑定和动态绑定结合起来,也就是说根据运行时传入对象的类型确定方法调用的过程。
重载是静态绑定,多态是动态绑定(运行时进行),双分派把多态放在重载之前,以实现在运行时动态判断执行那个子类的方法。因为编译器知道this所指向的实例的类型,因此将其作为参数传入到函数中就可以实现。

class Man : public Base {
public:
    int getSpeakRes(SpeakBase& speak) {
        return speak.speakWord(this);  //编译器知道this是哪个类型实例
    }
}

class Ghost : public Base {
public:
    int getSpeakRes(SpeakBase& speak) {
        return speak.speakWord(this);
    }
}

class Speak : public SpeakBase {
public:
    int speakWord(Man& man) {
        return "Man"; 
    }
    int speakWord(Ghost& ghost) {
        return "Ghost"; 
    }
}
class Board {
    drawFigure(aFigure) {
        aFigure.getDrawnOn(this)
    }
    drawTriangle(aTriangle) {
        // ...
    }
    drawSquare(aSquare) {
        // ...
    }
}

class Triangle extends Figure {
    getDrawnOn(aDrawableSurface) {
        aDrawableSurface.drawTriangle(this)
    }
}

class Square extends Figure {
    getDrawnOn(aDrawableSurface) {
        aDrawableSurface.drawSquare(this)
    }
}


----

let board = new Board();
let triangle = new Triangle();

board.drawFigure(triangle)

参考文章:

https://www.cnblogs.com/loveis715/p/4423464.html
http://yaoyao.codes/c++/2015/04/26/cpp-double-dispatch
https://www.typescriptlang.org/docs/handbook/functions.html#overloads
https://www.mikealche.com/software-development/refactor-long-if-or-switch-blocks-with-double-dispatch-in-javascript