Blady <
p....@orange.fr> writes:
> "Pour faire court, en Objective-C, une méthode de classe est un
> message qui est pris en charge par l’objet de la classe plutôt que par
> une instance de la classe."
>
http://sgamel.free.fr/spip.php?article123
>
> J'essayai avec un deuxième type tagged de simuler ce comportement...
> Est-ce possible ?
Pas directement car Ada n'a pas d'introspection. Il est sans doute
possible de le réimplémenter mais *pourquoi*?
Note que Ada est basé sur le typage statique alors qu'Objective-C
utilise le typage dynamique, basé sur l'introspection. Réconcilier les
deux est quasiment impossible. Si tu veux écrire de l'Objectivec-C en
Ada ("Objective-Ada"), il faut soit modifier le compilateur Ada, soit
accepter de mélanger le typage dynamique pour quelques types,
laborieusement décrits en termes Ada, et le typage statique pour tous
les autres (Integer, String, etc.).
Pour résumer: si tu aimes le typage dynamique tant que ça... pourquoi
écrire en Ada? Note que, outre Objective-C, d'autres langages utilisent
le même principe, à commencer par le premier langage orienté objet,
Smalltalk.
> package PA is
> type TAI is tagged record
> Name : String (1..10);
> end record;
> function init (Self : TAI) return TAI;
> type TAC is record
> Name : String (1..10);
> end record;
> function alloc (Self : TAC) return TAI;
> PAClass : constant TAC := (name => "Classe PA.");
> end;
> with PA; use PA;
> package PB is
> type TBI is new TAI with null record;
> function init (Self : TBI) return TBI;
> type TBC is new TAC;
Ici il y a une erreur: si le type TBC doit être capable de créer un
objet de type TBI, alors il doit obligatoirement redéfinir alloc. En
effet:
* TBI peut avoir des composants supplémentaires par rapport à TAI
* la nouvelle version de alloc doit retourner un TBI.
> PBClass : constant TBC := (name => "Classe PB.");
> end;
* et la nouvelle version de alloc doit indiquer à l'objet qu'elle crée
qu'elle appartient au type TBI et non TAI.
L'idiome accepté pour créer un objet de type arbitraire à l'intérieur
d'une classe de dérivation est:
package P is
type T (<>) is abstract tagged private;
function Alloc (parameters...) return T'Class;
private
type T is tagged null record;
end P;
Les discriminants inconnus (<>) obligent tout autre package à appeler
Alloc pour créer un objet de type T ou dérivé de T. Sans eux,
n'importe qui peut simplement écrire:
My_Object : P.T;
sans appeler Alloc. Avec les discriminants inconnus, il est obligé
d'écrire:
My_Object : P.T'Class := P.Alloc (parameters...);
et être préparé à ce que My_Object soit de n'importe quel type dérivé de
P.T. Bien entendu, ce sont les paramètres de Alloc qui déterminent le
type exact de l'objet créé. Et bien entendu, ce sont ces mêmes
paramètres qui rendent dynamique le type de l'objet créé.
--
Ludovic Brenta.