Ce n'est pas une question de style. C'est plus sur la bonne utilisation de la langue elle-même. Je suis assez nouveau pour la programmation et je suis totalement nouveau à l'objectif-C et à la cacao, mais après avoir lu sur la langue et examinez à travers certains échantillons de code, certains modèles d'utilisation continuent de simplement apparaître que cela n'a pas de sens pour moi. Ou plutôt ils semblent non optimaux dans mon esprit. J'espère que vous pouvez tout pouvoir m'éduquer dans les utilisations appropriées de certaines de ces constructions linguistiques.
interfaces VS protocoles P>
Je comprends les concepts d'interfaces et de mise en œuvre en ce qui concerne l'abstraction. Cependant, le modèle dominant que je vois dans l'exemple de code de l'objectif-C est le suivant ... p>
p > et ensuite le code client sous la forme de ... p> p> Cela me semble étrange. FOO semble être une implémentation dans mon esprit (irrégulier de la nommée malheureuse du mot-clé @interface). Les interfaces dans mon esprit n'exposent pas de variables d'instance. Un client de cette classe ne doit pas être exposé aux détails de ma mise en œuvre. P> objectif-c a le mot clé @protocol qui dans mon esprit est plus une interface que le mot clé @interface. Il vous permet de définir les méthodes et / ou les propriétés et c'est tout. Pas de mise en œuvre. Aucune variables d'instance. Il suffit d'interface. P> p> de sorte que le code client prendrait la forme .. . p> p> Cela semble (au moins pour moi) d'être un plus abstrait Utilisation de la langue et isole les clients des détails de la mise en œuvre, ils doivent ne pas dépendre de. Ma question est que devrais-je m'efforcer de suivre. Je comprends qu'il peut y avoir des situations où l'on est préférable sur l'autre mais en termes généraux, si l'on devrait être la norme et une exception? P> Certaines directives seraient appréciées. P> Merci ,
Roman p> p> code> p> code> p> code> p> code> p>
5 Réponses :
Premièrement, vous devez comprendre que vous faites une erreur classique: que la langue que vous connaissez déjà définit les termes utilisés dans toutes les langues - comme si une langue particulière a établi une nomenclature canonique. P>
Java a été commencé en 1990 à l'intérieur du soleil. Objective-C avait déjà été publié en 1986. Donc, si quelque chose, la terminologie d'interface de Java est en contradiction avec Objective-C, pas l'inverse. Cependant, l'interface a une longue histoire plus longue comme terme que l'une ou l'autre de ces langues. P>
L'idée derrière @interface dans l'objectif-c est décrite dans le Objective-C 2.0 Programmation Référence sur le langage : P>
interface forte> partie d'une spécification de classe Objective-C déclare son interface publique, qui incluent son nom de superclasse, ses variables d'instances et ses prototypes de méthodes publiques. P> blockQuote> Les méthodes d'instance sont des méthodes de classe sont publiques si elles sont déclarées dans l'interface. S'ils sont déclarés dans le @Implementalation, ils sont privés. P>
La mise en œuvre va dans la @Implemensation. Peut-être que vous êtes déroutant, c'est que Java n'a pas la notion d'une section de déclaration de classe comme dans l'objectif-c. La déclaration de classe déclare l'interface de classe de manière générique, sans spécificités de la mise en œuvre. Le @Implementatation a la mise en œuvre EM> EM>, qui correspond aux détails de la mise en œuvre de la classe @interface. P>
Ce n'est pas faux que l'objectif-c est différent de Java, c'est juste différent. P>
Mais vous avez raison, les protocoles sont les interfaces analogiques les plus proches des interfaces Java dans Objective-C, vous allez trouver. Ce n'est pas une superclasse pour quoi que ce soit, et n'a pas de mise en œuvre associée. Vous fournissez des protocoles beaucoup comme vous interfaces en Java. P>
Toutefois, remarquez que les protocoles ne sont pas aussi fréquents que des classes dans l'objectif-c. Cela devrait aider à guider votre pensée. P>
Je suis désolé si je suis arrivé comme comparant l'objectif-c à Java. Ce n'était pas mon intention. Le mot Java n'a jamais été apparu dans mon post original. Je disais simplement mon conflit interne sur ce que je considère comme une interface et que l'objectif-C estime être une interface. Le conseil de faire juste ce que l'autre code ne sait pas exactement avec moi en interne, mais cela a un certain mérite. Quand à Rome, etc. me donne quelque chose à penser.
Eh bien, votre utilisateur du terme "interface" de la manière dont Java utilise cela montre une compréhension basée sur la terminologie et les concepts de Java, mais ne sont pas nécessairement valables en dehors du cadre conceptuel de Java. L'étude des langues est un exercice extrêmement utile - apprendre à apprécier les variances intellectuelles pour informer votre utilisation d'autres langues.
(Je ne pensais pas que l'Asker ait directement piqûre à OBJ-C contre Java, mais vous avez raison, mais vous avez raison de dire qu'il y avait des overons qui suggéraient la confusion à l'usage dû à la terminologie dans les deux langues.) Objective-C a été réellement inventé en 1982 et Je l'ai trouvé très intéressant quand j'ai découvert que l'objectif-C avait une influence non triviale sur Java - Virtualschool .edu / objetivec / influenconjava.html
Je peux voir où vous venez d'en ce qui concerne la nommée du mot clé code> @interface code>, mais l'objectif-c utilise les deux mots-clés @interface code> et et @Implementatation code> pour différencier la déclaration de classe (interface) et sa définition (mise en œuvre). La partie @interface code> est généralement placée dans le fichier d'en-tête de classe et la partie @Implementatation code> dans le fichier source. Je suis d'accord avec vous à 100% que les variables d'instance internes ne devraient vraiment pas apparaître dans le fichier d'en-tête. Je ne suis pas sûr de ce qui a conduit à cette décision, mais ma meilleure estimation est que cela a à voir avec l'héritage de l'objet. Lorsque vous héritez d'une classe mère: #import "ParentClass.h"
@interface MyClass : ParentClass
...
Belle réponse, surtout pour aborder la question de l'OP sur les variables d'instance privée dans le fichier d'en-tête. Il suffit d'ajouter un lien à une autre question à propos de ce problème particulier: Stackoverflow.com/questions/966893/...
Objective-C est une couche vraiment mince sur C. Il vient vraiment gérer quelques tables de symboles pendant la compilation; Très semblable au préprocesseur C lui-même. Je suis sûr que la plupart des décisions devaient faire le codage plus facile (comme utiliser des bretelles carrées au lieu de parens, ils ont dû trouver quelque chose qu'ils pouvaient facilement analyser et extraire du code environnant. Probablement la raison pour laquelle ils ont choisi de suivre la syntaxe LISP Eh bien, plus facile d'analyser / extraire / remplacer. Néat hack cependant. Je pense que le fichier d'en-tête est entré uniquement, pas seulement un remplacement symbolique, c'est probablement pourquoi ils placent des variables.
Ils ne suivaient pas la syntaxe Lisp, mais plutôt la syntaxe SmallTalk. SmallTalk essaie de gérer autant que possible (y compris des énoncés conditionnels) grâce à une utilisation uniforme du passage du message, et la syntaxe reflète ce principe de conception en consistant essentiellement en blocs imbriqués.
NO-ONE n'a pas encore expliqué pourquoi les variables d'instance apparaissent dans le dans le cas de J'ai besoin de savoir comment faire une structure qui ressemble à: p> Par conséquent, la disposition ivar de la classe mère (et par induction toute catégorie em>) doit faire partie du contrat public de la classe, c'est-à-dire une partie de son @interface code> d'une classe Objective-C. Les objets sont implémentés sous forme de structures C contenant les variables d'instance. Lorsque vous créez une nouvelle sous-classe, un nouveau type de structure est défini avec toutes les ivars de la superclasse suivie des ivars de la nouvelle classe. La structure de Superclass doit contenir les ivars de sa superclasse em>, puis il s'agit de "tortues jusqu'au bout" à une structure qui représente les ivars de la classe de base. NsObject code> (et bien objet code>), la structure de la classe de base contient uniquement un ivar - un pointeur appelé ISA code> à la classe code> Structure de la catégorie code> la classe de ce objet. Donc, si je voulais la sous-classer comme ceci: p> @interface code>. Ce n'est peut-être pas jolie, mais là-bas. P> p>
En fait, cela n'est plus vrai dans le runtime non fragile (Mac OS X 64 bits X et iPhone), qui n'utilise pas des mises en page fixes. Lorsque vous construisez pour le temps d'exécution non fragile, vous pouvez implicitement ajouter des ivars dans la @Implementatation à l'aide de la directive @synthesize. Il n'y a pas de raison technique de ne pas autoriser un bloc {} ivar dans la @Implementatation; Le mot est que cela a été laissé de côté pour des raisons de temps. Des bugs ont été déposés.
À droite, trop vrai. Il n'y a pas de nécessité technique car la @interface est utilisée pour informer le compilateur des types et d'adhésion nécessaires lors de la compilation de la source qui fait référence à la classe sans causer une dépendance à la mise en œuvre. Si un ivar est @private, il n'y a pas de raison considérante de son existence dans le bloc @interface autre que la syntaxe.
@both Commentateurs: Droite. Je pensais que l'introduction de plusieurs roulements à ce stade n'était pas tout à fait approprié ;-)
J'ai également réalisé qu'il n'y a rien de vraiment forcer mes interfaces au public pour contenir des variables d'instance ... et le fichier de mise en œuvre ... p> @interface SomeDerivedFoo : Foo
{
// instance vars
}
// overrides of methods
Une alternative Si vous ne pouvez pas prendre en charge le temps d'exécution 64 bits et exclusivement synthétisé des ivars, est de créer un Cela vous permet d'écrire un code moins complexe, tout en vous donnant une marge de manœuvre pour changer de choses derrière le dos de votre client sans forcer un recompilement. P>
En tapant l'ivar comme code> ID code> Vous n'êtes de rien au code du client (un J'imagine que toutes vos classes publiques agissent comme des proxies aux implémentations privées auraient un peu ingérable. Gardez à l'esprit, si vous le faites, vous pouvez utiliser le transfert d'exécution pour réduire la quantité de code que vous devez écrire dans la classe publique. Voir ID code> ivar dans votre classe. Si vous devez revenir à votre classe après l'expédition et ajouter plus de variables d'instance, vous pouvez utiliser ce ID code> comme conteneur pour eux. P>
@private code> de toute façon). P>
- [NsObject ForwardingTargetforselector:] code>. Il est documenté dans 10.5 Notes de version de la Fondation P >