La différence est entre ce qu'est quelque chose et comment se comporte quelque chose.
Beaucoup de langues essaient de confondre les deux, mais ce sont des choses bien distinctes.
Si comment est quoi et comment est-il ...
Si tout hérite object
alors certains avantages se produisent comme: n'importe quelle variable d'objet peut contenir n'importe quelle valeur. Mais c'est aussi le hic, tout doit se comporter ( le comment ) comme un object
, et ressembler ( au quoi ) un object
.
Mais:
- Et si votre objet n'a pas de définition significative de l'égalité?
- Et s'il n'a pas de hachage significatif?
- Et si votre objet ne peut pas être cloné, mais que des objets peuvent l'être?
Soit le object
type devient essentiellement inutile - car l'objet ne fournit aucun point commun entre toutes les instances possibles. Ou il existera des objets qui ont une définition cassée / à cornes de chaussure / absurde d'une propriété universelle présumée trouvée sur object
laquelle prouve un comportement presque universel à l'exception d'un certain nombre de pièges.
Si ce qui n'est pas lié à comment
Alternativement, vous pouvez séparer le Quoi et le Comment . Ensuite, plusieurs types différents (avec rien en commun du tout quoi ) peuvent tous se comporter de la même manière que vu par le collaborateur le comment . En ce sens, l'idée d'un Iterator
n'est pas un quoi spécifique , mais un comment . Plus précisément, comment interagissez-vous avec une chose lorsque vous ne savez pas encore avec quoi vous interagissez.
Java (et similaire) permet des approches à cela en utilisant des interfaces. Une interface à cet égard décrit les moyens de communication, et implicitement un protocole de communication et d'action qui est suivi. Tout Quoi qui se déclare être d'un Comment donné , déclare qu'il soutient la communication et l'action pertinentes décrites par le protocole. Cela permet à tout collaborateur de compter sur la Comment et non s'enliser en précisant exactement quels Quelles « s peuvent être utilisés.
C ++ (et similaire) permet des approches à cela en tapant du canard. Un modèle ne se soucie pas si le type collaborateur déclare qu'il suit un comportement, juste que dans un contexte de compilation donné, avec lequel l'objet peut interagir d'une manière particulière. Cela permet aux pointeurs C ++ et aux opérateurs spécifiques dépassant les objets d'être utilisés par le même code. Parce qu'ils répondent à la liste de contrôle pour être considérés comme équivalents.
- prend en charge * a, a->, ++ a et a ++ -> itérateur d'entrée / transfert
- prend en charge * a, a->, ++ a, a ++, --a et a-- -> itérateur bidirectionnel
Le type sous-jacent n'a même pas besoin d'itérer un conteneur, il peut être n'importe quoi . De plus, cela permet à certains collaborateurs d'être encore plus génériques, imaginez qu'une fonction n'a besoin que a++
, un itérateur peut le satisfaire, tout comme un pointeur, un entier, tout comme n'importe quel objet à implémenter operator++
.
Spécifications inférieures et supérieures
Le problème avec les deux approches est sous et sur-spécifié.
L'utilisation d'une interface nécessite que l'objet déclare qu'il prend en charge un comportement donné, ce qui signifie également que le créateur doit l'imprégner dès le début. Cela fait que certains What 's ne font pas la coupe, car ils ne l'ont pas déclaré. Cela signifie également que toujours ce qui a un ancêtre commun, l'interface représentant le comment . Cela revient au problème initial de object
. Cela oblige les collaborateurs à sur-spécifier leurs besoins, tout en rendant simultanément certains objets inutilisables en raison d'un manque de déclaration, ou des accrochages cachés car un comportement attendu est mal défini.
L'utilisation d'un modèle nécessite que le collaborateur travaille avec un Quoi complètement inconnu , et à travers ses interactions il définit un Comment . Dans une certaine mesure, cela rend la rédaction des collaborateurs plus difficile, car elle doit analyser le Quoi pour ses primitives de communication (fonctions / champs / etc.) tout en évitant les erreurs de compilation, ou au moins indiquer comment un Quoi donné ne correspond pas à ses exigences pour le Comment . Cela permet au collaborateur d'exiger le minimum absolu de tout ce qui est donné, ce qui permet d'utiliser la plus large gamme de ce qui est utilisé. Malheureusement, cela a l'inconvénient de permettre des utilisations insensées d'objets qui fournissent techniquement les primitives de communication pour unComment , mais ne suivez pas le protocole implicite permettant à toutes sortes de mauvaises choses de se produire.
Itérateurs
Dans ce cas , un Iterator
est un Comment est un raccourci pour une description de l' interaction. Tout ce qui correspond à cette description est par définition un Iterator
. Savoir comment nous permet d'écrire des algorithmes généraux et d'avoir une courte liste de « comment » est donné un quoi spécifique qui doit être fourni afin de faire fonctionner l'algorithme. Cette liste est la fonction / propriétés / etc, leur implémentation prend en compte ce que spécifique est traité par l'algorithme.