J'ai décidé d'ajouter à cela puisque les deux réponses ci-dessus sont un peu incomplètes. J'étais moi-même curieux de cette question mais je n'ai pas trouvé de réponse et j'ai dû faire ma propre analyse. En général, il existe deux approches qui peuvent être utilisées pour implémenter des méthodes multiples dans des langages tels que C++ ou Java qui supportent à la fois la répartition dynamique unique et quelque chose comme l'identification de type typeof ou runtime. Pour le cas de double expédition, le modèle de visiteur est le plus commun (pour Arg1-> foo (Arg2)) et je suppose que dans la plupart des cas, il est préférable d'utiliser RTTI et les commutateurs ou les instructions if. On peut aussi généraliser l'approche du visiteur au n cas par exemple Arg1-> foo (Arg2, Arg3..ArgN) en enchaînant une série de distributions simples qui appellent des méthodes dans une structure arborescente qui différencie sur le type des arguments jusqu'à certains k et diviser le nombre de façons de l'argument k + 1. Par exemple, pour un simple cas d'envoi triple et deux instances de chaque type:
interface T1 {
public void f(T2 arg2, T3 arg3);
}
interface T2 {
public void gA(A a, T3 arg3)
public void gB(B b, T3 arg3)
}
interface T3 {
public void hAC(A a,C c);
public void hAD(A a,D d);
public void hBC(B b,C c);
public void hBD(B b,D d);
}
class A implements T1 {
public void f(T2 arg2, T3 arg3) {
arg2->gA(this,arg3);
}
}
class B implements T1 {
public void f(T2 arg2, T3 arg3) {
arg2->gB(this,arg3);
}
}
class C implements T2 {
public void gA(A a,T arg3) {
arg3->hAC(a, this);
}
public void gB(B b,T arg3) {
arg3->hBC(b, this);
}
}
class D implements T2 {
public void gA(A a,T arg3) {
arg3->hAD(a, this);
}
public void gB(B b,T arg3) {
arg3->hBD(b, this);
}
}
class E implements T3 {
public void hAC(A a,C c) {
System.out.println("ACE");
}
public void hAD(A a,D d) {
System.out.println("ADE");
}
public void hBC(B b,C c) {
System.out.println("BCE");
}
public void hBD(B b,D d) {
System.out.println("BDE");
}
}
class F implements T3 {
public void hAC(A a,C c) {
System.out.println("ACF");
}
public void hAD(A a,D d) {
System.out.println("ADF");
}
public void hBC(B b,C c) {
System.out.println("BCF");
}
public void hBD(B b,D d) {
System.out.println("BDF");
}
}
public class Test {
public static void main(String[] args) {
A a = new A();
C c = new C();
E e = new E();
a.f(c,e);
}
}
Bien que l'approche généralise le problème sont tout à fait évident. Pour chaque fonction de point final, dans le pire des cas, il faut écrire n-1 fonctions de répartition.
On peut obtenir quelque chose de similaire avec l'identification du type d'exécution via l'opérateur instanceOf:
class Functions
{
static void f(A a,C c,E e) {
System.out.println("ACE");
}
static void f(A a,C c,F f) {
System.out.println("ACF");
}
static void f(A a,D d,E e) {
System.out.println("ADE");
}
static void f(A a,D d,F f) {
System.out.println("ADF");
}
static void f(B b,C c,E e) {
System.out.println("BCE");
}
static void f(B b,C c,F f) {
System.out.println("BCF");
}
static void f(B b,D d,E e) {
System.out.println("BDE");
}
static void F(B b,D d,F f) {
System.out.println("BDF");
}
static void dispatch(T1 t1, T2 t2, T3 t3) {
if(t1 instanceOf A)
{
if(t2 instance of C) {
if(t3 instance of E) {
Function.F((A)t1, (C)t2, (E)t3);
}
else if(t3 instanceOf F) {
Function.F((A)t1, (C)t2, (F)t3);
}
}
else if(t2 instance of D) {
if(t3 instance of E) {
Function.F((A)t1, (D)t2, (E)t3);
}
else if(t3 instanceOf F) {
Function.F((A)t1, (D)t2, (F)t3);
}
}
}
else if(t1 instanceOf B) {
if(t2 instance of C) {
if(t3 instance of E) {
Function.F((B)t1, (C)t2, (E)t3);
}
else if(t3 instanceOf F) {
Function.F((B)t1, (C)t2, (F)t3);
}
}
else if(t2 instance of D) {
if(t3 instance of E) {
Function.F((B)t1, (D)t2, (E)t3);
}
else if(t3 instanceOf F) {
Function.F((B)t1, (D)t2, (F)t3);
}
}
}
}
}
La deuxième solution peut probablement être encore simplifiée en utilisant la réflexion.
Est-ce que votre exemple evem compile? (Nombre de conversions opérandes). et pourriez-vous clarifier un peu plus quel est le problème? Ce n'est pas clair en ce moment de ce que vous cherchez – n247s
Je n'ai pas écrit les constructeurs donc il ne compile pas, c'est juste un exemple. Ce que je veux, c'est appeler Multiplication :: eval (Integer, Matrix) lorsque l'objet appelé a le type statique Opérateur et type d'exécution Multiplication et ses arguments ont un type statique Types d'opérandes et d'exécution Entier et Matrix. Il existe un modèle pour cela, lorsque la méthode eval n'a qu'un argument, elle est appelée dispatch multiple. Je veux la même chose pour 2 (ou plus) arguments. – biowep
Dès que vous définissez 'Operator mul;' vous êtes limité au contrat défini par 'Operator'. Donc, à moins de définir la méthode 'eval (Integer, Matrix)' dans la classe 'Operator' (ou l'un de ses parents), vous ne pourrez pas l'invoquer. Au lieu de déclarer qu'il est de type 'Operator', vous pouvez le changer en' Multiplication'. – nickb