![]()
|
|
L'Objective C est un langage dérivé du C et inspiré par SmallTalk, qui essaie de marier la performance du premier et la souplesse de développement du second. Nous allons survoler ensemble ses caractéristiques principales, afin d'appréhender sa philosophie. Une connaissance du C, ainsi que de la programmation objet, est nécessaire pour comprendre pleinement l'article. Vue
globale Un premier
exemple #import <ObjC/Object.h> #import <stdio.h> Objective C différencie la définition d'un objet (qui prend en général place dans un fichier d'extension .h) de son implémentation (qui prend place dans un fichier d'extension .m). La définition d'un objet est introduite par le mot clé @interface. Suivent le nom de l'objet à définir, le nom de l'objet mère, les données membres, ainsi que les méthodes de l'objet (une méthode est en gros une fonction associée à un objet). L'objet que nous allons créer, MonObjet, se définit comme suit : @interface MonObjet : Object
{
int mValeur;
}
-(void)action;
-(void)prefixe;
@end
Cet objet hérite directement de l'objet de base Object, comporte un membre sous la forme d'un entier, et définit deux méthodes d'instance : action, qui ne prend aucun paramètre et renvoie void, et prefixe, qui fait de même. Chaque méthode est physiquement une fonction C, mais son appel ne passe pas uniquement par un appel de fonction. C'est en fait un message qui est envoyé à MonObjet, lui intimant l'ordre d'appeler la méthode en question. Nous verrons plus tard comment. L'implémentation est aussi triviale que la définition. Le mot clé l'introduisant est @implementation. @implementation MonObjet
-(void)action
{
[self prefixe];
printf ("L'objet vaut %d\n", mValeur);
}
-(void)prefixe
{
puts ("Prefixe");
}
@end
La méthode action commence par faire un appel à la méthode prefixe, appartenant au même objet. Nous apercevons en première ligne d'action le mécanisme d'appel de méthode, qui utilise des crochets [] : le destinataire du message, ici l'objet lui-même représenté par self, est suivi du nom de la méthode à exécuter. La simplicité de cette syntaxe n'a d'égale que sa puissance. En effet, le passage de message peut aussi s'effectuer d'un espace d'adressage à un autre, c'est-à-dire d'un programme à un autre, ou d'une machine à une autre, sans grande complication supplémentaire ! Dériver un objet, pour redéfinir une de ses méthodes par exemple, est une nouvelle fois d'une simplicité désarmante : @interface MonObjetDerive : MonObjet
-(void)prefixe;
@end
@implementation MonObjetDerive
-(void)prefixe
{
puts ("Prefixe dérivé");
}
@end
MonObjetDerive hérite directement de l'objet que nous venons de créer un peu plus tôt. Il modifie le comportement de la méthode prefixe. Cette redéfinition passe par une déclaration dans l'@interface, et une nouvelle implémentation, dans @implementation bien entendu. Le corps de notre programme principal commence par le traditionnel : int main (int argc, const char *argv[])
{
Nous allons ensuite créer
un objet MonObjetDerive. Il faut tout d'abord allouer la place
nécessaire, puis initialiser l'objet (par
défaut, l'espace occupé par l'objet est mis
à zéro). Ces actions sont
réalisées par les méthodes
alloc et init,
qui appartiennent à l'objet de base Object
et qui ont été héritées tout au
long du processus de dérivation. Ces méthodes
sont des méthodes de classe, et pas d'instance. En
effet, il est impossible que ces méthodes
appartiennent à un objet, puisque l'objet n'est pas
encore créé ! MonObjet *objet = [[MonObjetDerive alloc] init]; Il est tout à fait
légal d'assigner un pointeur sur un objet
MonObjetDerive à un pointeur sur un objet
ObjetDerive, vu qu'un objet MonObjetDerive EST un objet MonObjet. Cependant, le typage n'est pas si
rigoureux en Objective C qu'en C, en C++ ou en Java. Il
n'est qu'une indication pour le programmeur, la
résolution de l'appel d'une méthode se faisant
à l'exécution : Objective C
vérifiera donc à
l'exécution que
l'objet est à même de recevoir et
d'exécuter le message qui lui est destiné,
quel que soit le typage utilisé lors de la
programmation. Avec pour conséquence remarquable
qu'envoyer un message à un objet NULL
est une non-opération : rien à voir avec
C ou C++, pour lesquels les actions sur NULL
sont souvent synonymes de plantages. [objet action]; L'appel à la
méthode action
de notre cru, nécessite quelques commentaires.
L'action de MonObjetDerive est l'action
de MonObjet. Celle-ci appelle prefixe. Or prefixe
a été redéfinie dans MonObjetDerive. Vu que l'objet que nous avons
créé est un MonObjetDerive (bien qu'il soit utilisé au
travers d'un pointeur sur un MonObjet), c'est bien prefixe
de MonObjetDerive qui est appelé. Prefixe dérivé L'objet vaut 0 Afin de terminer le programme dans les règles de l'art, on libère la place prise par l'objet précédemment créé, et on fait retourner à main un code d'erreur rassurant : [objet free]; exit(0); } Conclusion Nous verrons dans un prochain article quelques autres aspects remarquables de ce langage.
|
|