(defgenericcollide(xy))(defclassasteroid()())(defclassspaceship()())(defmethodcollide-with((xasteroid)(yasteroid));; deal with asteroid hitting asteroid)(defmethodcollide-with((xasteroid)(yspaceship));; deal with asteroid hitting spaceship)(defmethodcollide-with((xspaceship)(yasteroid));; deal with spaceship hitting asteroid)(defmethodcollide-with((xspaceship)(yspaceship));; deal with spaceship hitting spaceship)
collide_with(x::Asteroid,y::Asteroid)=...# deal with asteroid hitting asteroidcollide_with(x::Asteroid,y::Spaceship)=...# deal with asteroid hitting spaceshipcollide_with(x::Spaceship,y::Asteroid)=...# deal with spaceship hitting asteroidcollide_with(x::Spaceship,y::Spaceship)=...# deal with spaceship hitting spaceship
/* Groovy implementation of C# example above Late binding works the same when using non-static methods or compiling class/methods statically (@CompileStatic annotation)*/classProgram{staticvoidmain(String[]args){printlnCollider.collide(newAsteroid(101),newSpaceship(300))printlnCollider.collide(newAsteroid(10),newSpaceship(10))printlnCollider.collide(newSpaceship(101),newSpaceship(10))}}classCollider{staticStringcollide(SpaceObjectx,SpaceObjecty){(x.size>100&&y.size>100)?"big-boom":collideWith(x,y)// Dynamic dispatch to collideWith method}privatestaticStringcollideWith(Asteroidx,Asteroidy){"a/a"}privatestaticStringcollideWith(Asteroidx,Spaceshipy){"a/s"}privatestaticStringcollideWith(Spaceshipx,Asteroidy){"s/a"}privatestaticStringcollideWith(Spaceshipx,Spaceshipy){"s/s"}}classSpaceObject{intsizeSpaceObject(intsize){this.size=size}}@InheritConstructorsclassAsteroidextendsSpaceObject{}@InheritConstructorsclassSpaceshipextendsSpaceObject{}
import{multi,method}from'@arrows/multimethod'classAsteroid{}classSpaceship{}constcollideWith=multi(method([Asteroid,Asteroid],(x,y)=>{// deal with asteroid hitting asteroid}),method([Asteroid,Spaceship],(x,y)=>{// deal with asteroid hitting spaceship}),method([Spaceship,Asteroid],(x,y)=>{// deal with spaceship hitting asteroid}),method([Spaceship,Spaceship],(x,y)=>{// deal with spaceship hitting spaceship}),)
可以使用库扩展来向Python增加多分派。例如,最早的模块multimethods.py[10],它为Python提供了CLOS风格的多方法而不用变更语言的底层语法或关键字。在功能上,这非常类似于CLOS例子,但是语法是常规Python的。[b]Guido van Rossum使用Python 2.4介入的修饰器(decorator),出品了多方法的具有简化了的语法的一个简单实现,他为此定义了multimethod修饰器[11]。[c]
multipledispatch[12]采用的形式与之一致。
frommultimethodimportmultimethodclassAsteroid():passclassSpaceship():pass@multimethoddefcollide_with(x:Asteroid,y:Asteroid):'''deal with asteroid hitting asteroid'''print("asteroid hitting asteroid")@multimethoddefcollide_with(x:Asteroid,y:Spaceship):'''deal with asteroid hitting spaceship'''print("asteroid hitting spaceship")@multimethoddefcollide_with(x:Spaceship,y:Asteroid):'''deal with spaceship hitting asteroid'''print("spaceship hitting asteroid")@multimethoddefcollide_with(x:Spaceship,y:Spaceship):'''deal with spaceship hitting spaceship'''print("spaceship hitting spaceship")
typedefvoid(*CollisionCase)(void);voidcollision_AA(void){/* handle Asteroid-Asteroid collision */};voidcollision_AS(void){/* handle Asteroid-Spaceship collision */};voidcollision_SA(void){/* handle Spaceship-Asteroid collision */};voidcollision_SS(void){/* handle Spaceship-Spaceship collision*/};typedefenum{THING_ASTEROID=0,THING_SPACESHIP,THING_COUNT/* not a type of thing itself, instead used to find number of things */}Thing;CollisionCasecollisionCases[THING_COUNT][THING_COUNT]={{&collision_AA,&collision_AS},{&collision_SA,&collision_SS}};voidcollide(Thinga,Thingb){(*collisionCases[a][b])();}intmain(void){collide(THING_SPACESHIP,THING_ASTEROID);}
interfaceCollideable{voidcollideWith(finalCollideableother);/* These methods would need different names in a language without method overloading. */voidcollideWith(finalAsteroidasteroid);voidcollideWith(finalSpaceshipspaceship);}classAsteroidimplementsCollideable{publicvoidcollideWith(finalCollideableother){// Call collideWith on the other object.other.collideWith(this);}publicvoidcollideWith(finalAsteroidasteroid){// Handle Asteroid-Asteroid collision.}publicvoidcollideWith(finalSpaceshipspaceship){// Handle Asteroid-Spaceship collision.}}classSpaceshipimplementsCollideable{publicvoidcollideWith(finalCollideableother){// Call collideWith on the other object.other.collideWith(this);}publicvoidcollideWith(finalAsteroidasteroid){// Handle Spaceship-Asteroid collision.}publicvoidcollideWith(finalSpaceshipspaceship){// Handle Spaceship-Spaceship collision.}}
import{multi,method,Multi}from'@arrows/multimethod'classAsteroid{}classSpaceship{}typeCollideWith=Multi&{(x:Asteroid,y:Asteroid):void(x:Asteroid,y:Spaceship):void(x:Spaceship,y:Asteroid):void(x:Spaceship,y:Spaceship):void}constcollideWith:CollideWith=multi(method([Asteroid,Asteroid],(x,y)=>{// deal with asteroid hitting asteroid}),method([Asteroid,Spaceship],(x,y)=>{// deal with asteroid hitting spaceship}),method([Spaceship,Asteroid],(x,y)=>{// deal with spaceship hitting asteroid}),method([Spaceship,Spaceship],(x,y)=>{// deal with spaceship hitting spaceship}),)
frommultimethodsimportDispatchfromgame_objectsimportAsteroid,Spaceshipfromgame_behaviorsimportas_func,ss_func,sa_funccollide=Dispatch()collide.add_rule((Asteroid,Spaceship),as_func)collide.add_rule((Spaceship,Spaceship),ss_func)collide.add_rule((Spaceship,Asteroid),sa_func)defaa_func(a,b):"""Behavior when asteroid hits asteroid."""# ...define new behavior...collide.add_rule((Asteroid,Asteroid),aa_func)
@multimethod(Asteroid,Asteroid)defcollide(a,b):"""Behavior when asteroid hits a asteroid."""# ...define new behavior...@multimethod(Asteroid,Spaceship)defcollide(a,b):"""Behavior when asteroid hits a spaceship."""# ...define new behavior...# ... define other multimethod rules ...
Stroustrup, Bjarne; Solodkyy, Yuriy; Pirkelbauer, Peter. Open Multi-Methods for C++(PDF). ACM 6th International Conference on Generative Programming and Component Engineering. 2007 [2014-07-13]. (原始内容存档(PDF)于2021-04-29).