La differenza è tra cos'è qualcosa e come si comporta qualcosa.
Molte lingue cercano di confondere le due cose insieme, ma sono cose abbastanza distinte.
Se come è cosa e cosa è come ...
Se tutto eredita da object
allora, si verificano alcuni vantaggi come: qualsiasi variabile di oggetto può contenere qualsiasi valore in assoluto. Ma questo è anche il problema, tutto deve comportarsi ( il come ) come un object
, e sembrare ( il cosa ) un object
.
Ma:
- Cosa succede se il tuo oggetto non ha una definizione significativa di uguaglianza?
- E se non avesse un hash significativo?
- Cosa succede se il tuo oggetto non può essere clonato, ma gli oggetti possono essere?
O il object
tipo diventa essenzialmente inutile, a causa dell'oggetto che non fornisce alcuna comunanza tra tutte le possibili istanze. Oppure esisteranno oggetti che hanno una definizione spezzata / con il clacson / assurda di una presunta proprietà universale trovata sulla object
quale si rivela un comportamento quasi universale tranne che per un certo numero di gotchas.
Se cosa non è legato a come
In alternativa puoi tenere separati cosa e come . Quindi diversi tipi (con nulla in comune per niente che cosa ) possono tutti comportarsi allo stesso modo visto dal collaboratore come . In questo senso l'idea di un Iterator
non è un cosa specifico , ma un come . In particolare Come interagisci con una cosa quando non sai ancora con cosa stai interagendo.
Java (e simili) consentono approcci a questo utilizzando interfacce. Un'interfaccia a questo proposito descrive i mezzi di comunicazione e implicitamente un protocollo di comunicazione e azione che viene seguito. Qualsiasi cosa che si dichiari di essere di un dato How , afferma che supporta la comunicazione e l'azione pertinenti delineate dal protocollo. Ciò consente a qualsiasi collaboratore di fare affidamento sul How e di non impantanarsi specificando esattamente che cosa è possibile utilizzare.
C ++ (e simili) consentono approcci a questo tramite la tipizzazione duck. A un modello non importa se il tipo collaboratore dichiara di seguire un comportamento, solo che in un determinato contesto di compilazione, l'oggetto può essere interagito in un modo particolare. Ciò consente ai puntatori C ++ e agli oggetti che sovrastano operatori specifici di essere utilizzati dallo stesso codice. Perché soddisfano la lista di controllo per essere considerati equivalenti.
- supporta * a, a->, ++ a e a ++ -> input / forward iterator
- supporta * a, a->, ++ a, a ++, --a e a-- -> iteratore bidirezionale
Il tipo sottostante non deve nemmeno iterare un contenitore, potrebbe essere qualsiasi cosa . Inoltre, consente ad alcuni collaboratori di essere ancora più generici, immaginare che una funzione ha solo bisogno a++
, un iteratore può soddisfarlo, così può un puntatore, così può un numero intero, così l'implementazione di qualsiasi oggetto operator++
.
Sotto e sopra le specifiche
Il problema con entrambi gli approcci è sotto e sopra le specifiche.
L'uso di un'interfaccia richiede che l'oggetto dichiari di supportare un determinato comportamento, il che significa anche che il creatore deve ispirarlo fin dall'inizio. Questo fa sì che alcuni Che cosa non effettuino il taglio, in quanto non lo hanno dichiarato. Significa anche che qualunque cosa abbia un antenato comune, l'interfaccia che rappresenta il How . Questo fa risalire al problema iniziale di object
. Questo fa sì che i collaboratori specifichino eccessivamente i loro requisiti, causando al contempo alcuni oggetti inutilizzabili a causa della mancanza di una dichiarazione o nascondendo i gotcha poiché un comportamento previsto è scarsamente definito.
L'uso di un modello richiede che il collaboratore lavori con un Cosa completamente sconosciuto e, attraverso le sue interazioni, definisce un Come . In una certa misura ciò rende più difficile la scrittura di collaboratori, in quanto deve analizzare il What for per le sue primitive di comunicazione (funzioni / campi / ecc.) Evitando errori di compilazione, o almeno sottolineare come un dato What non corrisponde ai suoi requisiti per il How . Ciò consente al collaboratore di richiedere il minimo assoluto da qualsiasi dato Cosa , consentendo la più ampia gamma di ciò che deve essere utilizzato. Sfortunatamente questo ha il rovescio della medaglia nel consentire usi insensati di oggetti che tecnici forniscono le primitive comunicative per un datoCome , ma non seguire il protocollo implicito che consente il verificarsi di ogni sorta di cose cattive.
iteratori
In questo caso un Iterator
è un modo in cui è una scorciatoia per una descrizione dell'interazione. Tutto ciò che corrisponde a quella descrizione è per definizione un Iterator
. Sapere come ci permette di scrivere algoritmi generali e avere un breve elenco di " Come viene dato un cosa specifico " che deve essere fornito per far funzionare l'algoritmo. Tale elenco è la funzione / proprietà / ecc., La loro implementazione tiene conto dello specifico Cosa viene gestito dall'algoritmo.