Diamant problem

I datalogi , den diamant problemet (eller diamant problem i nogle videnskabelige artikler) forekommer hovedsageligt i objektorienteret programmering , når sproget tillader multipel nedarvning . Hvis en klasse D arver fra to klasse B og C, selv børn af samme klasse A, opstår der et konfliktproblem, når funktioner eller felter i klasse B og C har samme navn. Navnet på dette problem kommer fra formen af ​​arveskemaet i klasse A, B, C og D i dette tilfælde.

For eksempel, i tilfælde af en grafisk grænseflade , kunne en klasse Buttonarve to klasser Rectangle(styre dens udseende) og Clickable(administrere museklik), og disse to klasser arve fra en klasse Object. Hvis klassen Objectdefinerer funktionen equals(håndtering af sammenligningen mellem objekter), hvilke to underklasser Rectangleog Clickableudvider denne funktion for at tilpasse den til deres særlige forhold, hvilken af ​​funktionerne equalsi Rectangleeller i Clickableklassen Buttonskal den bruge? Vilkårligt valg af kun en af ​​de to funktioner vil miste interessen for arv; brug af de to funktioner udgør problemet med rækkefølgen af ​​opkaldene, kombinationen af ​​resultater (eller fejl), den mulige redundans af deres effekter osv.

Opløsning nærmer sig

Ved at forbyde tvetydighed

I C ++ kaldes disse problemer tvetydigheder: Compileren kaster en fejl, hvis den ikke kan bestemme, hvilken metode der skal bruges. Udvikleren skal derefter enten omdefinere metoden i den afledte klasse eller bruge operatøren for opløsningsområde (: :) til at angive den metode, der skal bruges.

Sprog som Eiffel eller OCaml tilbyder mere avancerede konstruktioner for at hjælpe udvikleren med at løse disse uklarheder.

Ved at indstille en prioritetsrækkefølge

Dette består i at definere en lineariseringsalgoritme til at opbygge en metodeopløsningsrækkefølge ( MRO  : Method Resolution Order ). En god linearisering skal respektere visse begrænsninger:

Programmeringssprog kan løse dette problem på forskellige måder:

Ved at reservere flere arv til grænseflader

Andre sprog forbyder simpelthen flere arv (såsom Ada , Ruby , Objective-C , PHP , C # , Delphi / Free Pascal og Java ): en klasse arver kun fra hinanden, men kan implementere en liste over grænseflader . Disse grænseflader indeholder kun abstrakte metoder, dvs. de indeholder ingen kode. Det er op til klassen at implementere alle metoderne i alle dets grænseflader. I dette tilfælde kan grænseflader assimileres med kontrakter, der tvinger alle klasser, der bruger dem, til at implementere de samme metoder.

Noter og referencer

  1. (i) Navn Ambiguities  " , Microsoft Developer Network .
  2. (in) "En monoton superklasse linearisering for Dylan" (version af 15. april 2012 på internetarkivet ) , haahr.tempdomainname.com, 28. juni 1996.
  3. (in) Method Resolution Order  " , Pythons historie , 23. juni 2010.
  4. (in) Michele Simionato The Python 2.3 Method Resolution Order  " , Python.org.
  5. Errata: siden Java 8 er det muligt at simulere diamantarv med defaultinterface- metoder . Disse giver dig mulighed for at implementere kode direkte i grænsefladen og derfor se en klassefordel ved implementeringen af ​​to metoder med samme navn i to forskellige grænseflader. Det er dog stadig ikke muligt at arve fra to forskellige klasser på dette sprog.

Bibliografi