Nel primo semestre ci sono stati introdotti concetti OOP come incapsulamento, nascondimento dei dati, modularità, eredità e così via attraverso Java e UML. (Java è il mio primo linguaggio di programmazione)
Nessuno di questi sono concetti OOP. Esistono tutti al di fuori di OO, indipendentemente da OO e molti addirittura sono stati inventati prima di OO.
Quindi, se pensi che questo sia OO, allora la tua conclusione è giusta: puoi fare tutto ciò nei linguaggi procedurali, perché non hanno nulla a che fare con OO .
Ad esempio, uno dei documenti fondamentali sulla modularità è sui criteri da utilizzare per la decomposizione dei sistemi in moduli . Non c'è menzione di OO lì dentro. (Fu scritto nel 1972, a quel tempo OO era ancora una nicchia oscura, nonostante avesse già più di un decennio.)
Sebbene l' astrazione dei dati sia importante in OO, è più una conseguenza della funzionalità primaria di OO (messaggistica) che non una funzione di definizione. Inoltre, è molto importante ricordare che esistono diversi tipi di astrazione dei dati. I due tipi più comuni di astrazione dei dati attualmente in uso (se ignoriamo "nessuna astrazione di sorta", che è probabilmente ancora utilizzata più delle altre due combinate), sono i tipi di dati astratti e gli oggetti . Quindi, semplicemente dicendo "Informazioni nascoste", "Incapsulamento" e "Astrazione dei dati", non hai detto nulla su OO, poiché OO è solo una forma di astrazione dei dati, e i due sono in realtà fondamentalmente diversi:
- Con i tipi di dati astratti, il meccanismo per l'astrazione è il sistema dei tipi ; è il sistema di tipi che nasconde l'implementazione. (Il sistema dei tipi non deve necessariamente essere statico.) Con Oggetti, l'implementazione è nascosta dietro un'interfaccia procedurale , che non richiede tipi. (Ad esempio, può essere implementato con chiusure, come avviene in ECMAScript.)
- Con i tipi di dati astratti, le istanze di ADT diversi sono incapsulate l'una dall'altra, ma le istanze dello stesso ADT possono ispezionare e accedere reciprocamente alla rappresentazione e all'implementazione privata. Gli oggetti sono sempre incapsulati da tutto . Solo l'oggetto stesso può ispezionare la propria rappresentazione e accedere alla propria implementazione privata. Nessun altro oggetto , nemmeno altri oggetti dello stesso tipo, altre istanze della stessa classe, altri oggetti con lo stesso prototipo, cloni dell'oggetto o qualsiasi altra cosa possano farlo. Nessuno .
Ciò significa, in ogni caso, che in Java le classi non sono orientate agli oggetti. Due istanze della stessa classe possono accedere reciprocamente alla rappresentazione e all'implementazione privata. Pertanto, le istanze delle classi non sono oggetti, in realtà sono istanze ADT. Java interface
s, tuttavia, non forniscono l'astrazione dei dati orientato agli oggetti. Quindi, in altre parole: solo le istanze di interfacce sono oggetti in Java, mentre le istanze di classi no.
Fondamentalmente, per i tipi, è possibile utilizzare solo interfacce. Ciò significa che i tipi di parametri di metodi e costruttori, i tipi restituiti di metodi, i tipi di campi di istanza, i campi statici e i campi locali, l'argomento per un instanceof
operatore o un operatore di cast e gli argomenti di tipo per un costruttore di tipo generico devono sempre essere interfacce. Una classe può essere utilizzata solo direttamente dopo l' new
operatore, da nessun'altra parte.
Ad esempio, per la modularità possiamo semplicemente dividere il programma in molti piccoli programmi che eseguono attività ben definite il cui codice è contenuto in file separati. Questi programmi interagirebbero tra loro attraverso i loro input e output ben definiti. I file possono essere protetti (crittografati?) Per ottenere l'incapsulamento. Per il riutilizzo del codice possiamo semplicemente chiamare quei file ogni volta che sono necessari in nuovi programmi. Questo non cattura tutto ciò che è OOP o mi sto perdendo qualcosa di molto ovvio?
Quello che descrivi è OO.
Questo è davvero un buon modo di pensare a OO. In realtà, è esattamente quello che gli inventori originali di OO avevano in mente. (Alan Kay ha fatto un ulteriore passo avanti: ha immaginato un sacco di piccoli computer che si scambiano messaggi attraverso la rete.) Quello che chiami "programma" è di solito chiamato "oggetto" e invece di "chiamata" di solito diciamo "invia un messaggio ".
L'orientamento agli oggetti è tutto incentrato sulla messaggistica ( nota anche come invio dinamico ). Il termine "Object Oriented" è stato coniato dal Dr. Alan Kay, il principale designer di Smalltalk, e lo definisce così :
OOP per me significa solo messaggistica, conservazione locale, protezione e occultamento del processo statale ed estremo vincolo tardivo di tutte le cose.
Analizziamo questo:
- messaggistica ("invio metodo virtuale", se non si ha familiarità con Smalltalk)
- il processo statale dovrebbe essere
- mantenuto localmente
- protetta
- nascosto
- estremo legame tardivo di tutte le cose
Dal punto di vista dell'implementazione, la messaggistica è una chiamata di procedura in ritardo e, se le chiamate di procedura sono in ritardo, non è possibile sapere in fase di progettazione ciò che si intende chiamare, quindi non è possibile fare ipotesi sulla rappresentazione concreta dello stato. Quindi, in realtà si tratta di messaggistica, il late-binding è un'implementazione della messaggistica e l'incapsulamento ne è una conseguenza.
In seguito ha chiarito che " La grande idea è" messaggistica ", e si rammarica di averla definita" orientata agli oggetti "anziché" orientata ai messaggi ", poiché il termine" orientato agli oggetti "pone l'accento sulla cosa non importante (oggetti ) e distrae da ciò che è veramente importante (messaggistica):
Solo un gentile promemoria che ho fatto un po 'di fatica all'ultimo OOPSLA per cercare di ricordare a tutti che Smalltalk NON è solo la sua sintassi o la libreria di classi, non si tratta nemmeno di classi. Mi dispiace di aver coniato molto tempo fa il termine "oggetti" per questo argomento perché molte persone si concentrano sull'idea minore.
La grande idea è "messaggistica" - ecco di cosa si occupa il kernal di Smalltalk / Squeak (ed è qualcosa che non è mai stato del tutto completato nella nostra fase PARC Xerox). I giapponesi hanno una piccola parola - ma - per "ciò che sta in mezzo" - forse l'equivalente inglese più vicino è "interstiziale". La chiave per realizzare sistemi grandi e coltivabili è molto di più per progettare come comunicano i suoi moduli piuttosto che quali dovrebbero essere le loro proprietà e comportamenti interni. Pensa a Internet: per vivere, (a) deve consentire molti diversi tipi di idee e realizzazioni che vanno oltre ogni singolo standard e (b) per consentire vari gradi di interoperabilità sicura tra queste idee.
(Certo, oggi, la maggior parte delle persone non si concentra nemmeno sugli oggetti ma sulle classi, il che è ancora più sbagliato.)
La messaggistica è fondamentale per OO, sia come metafora che come meccanismo.
Se invii a qualcuno un messaggio, non sai cosa ci fanno. L' unica cosa che puoi osservare è la loro risposta. Non sai se hanno elaborato il messaggio da soli (cioè se l'oggetto ha un metodo), se hanno inoltrato il messaggio a qualcun altro (delega / proxy), se lo hanno persino capito. Ecco cos'è l'incapsulamento, questo è OO. Non puoi nemmeno distinguere un proxy dalla realtà, purché risponda a come ti aspetti.
Un termine più "moderno" per "messaggistica" è "invio dinamico del metodo" o "chiamata del metodo virtuale", ma che perde la metafora e si concentra sul meccanismo.
Quindi, ci sono due modi per guardare la definizione di Alan Kay: se la guardi da sola, potresti osservare che la messaggistica è fondamentalmente una chiamata di procedura in ritardo e l'associazione in ritardo implica l'incapsulamento, quindi possiamo concludere che # 1 e # 2 sono in realtà ridondanti, e OO si basa sul late-binding.
Tuttavia, in seguito ha chiarito che la cosa importante è la messaggistica, e quindi possiamo guardarla da una prospettiva diversa: la messaggistica è in ritardo. Ora, se la messaggistica fosse l' unica cosa possibile, allora il n. 3 sarebbe banalmente vero: se c'è solo una cosa, e quella cosa è in ritardo, allora tutte le cose sono in ritardo. E ancora una volta, l'incapsulamento segue dalla messaggistica.
Punti simili sono stati anche sottolineati in On Understanding Data Abstraction, rivisitato da William R. Cook e anche nella sua proposta di definizioni semplificate e moderne di "oggetto" e "oggetto orientato" :
L'invio dinamico delle operazioni è la caratteristica essenziale degli oggetti. Significa che l'operazione da invocare è una proprietà dinamica dell'oggetto stesso. Le operazioni non possono essere identificate staticamente e in generale non è possibile [sapere] esattamente quale operazione verrà eseguita in risposta a una determinata richiesta, tranne eseguendola. Questo è esattamente lo stesso delle funzioni di prima classe, che vengono sempre inviate in modo dinamico.
In Smalltalk-72 non c'erano nemmeno oggetti! C'erano solo flussi di messaggi che venivano analizzati, riscritti e reindirizzati. Prima sono arrivati i metodi (metodi standard per analizzare e reindirizzare i flussi di messaggi), successivamente sono arrivati gli oggetti (raggruppamenti di metodi che condividono un certo stato privato). L'eredità è arrivata molto più tardi e le classi sono state introdotte solo come un modo per sostenere l'eredità. Se il gruppo di ricerca di Kay avesse già saputo dei prototipi, probabilmente non avrebbero mai introdotto le classi.
Benjamin Pierce in Tipi e linguaggi di programmazione sostiene che la caratteristica principale di Orientamento agli oggetti è la ricorsione aperta .
Quindi: secondo Alan Kay, OO si occupa di messaggistica. Secondo William Cook, OO si basa sulla spedizione di metodi dinamici (che è davvero la stessa cosa). Secondo Benjamin Pierce, OO è tutto su Open Recursion, il che significa sostanzialmente che gli auto-riferimenti vengono risolti dinamicamente (o almeno è un modo di pensare), o, in altre parole, i messaggi.
Come puoi vedere, la persona che ha coniato il termine "OO" ha una visione piuttosto metafisica degli oggetti, Cook ha una visione piuttosto pragmatica e Pierce una visione matematica molto rigorosa. Ma la cosa importante è: il filosofo, il pragmatico e il teorico sono tutti d'accordo! La messaggistica è il pilastro di OO. Periodo.
Nota che qui non si parla di eredità! L'ereditarietà non è essenziale per OO. In generale, la maggior parte dei linguaggi OO ha un modo per riutilizzare l'implementazione, ma ciò non deve necessariamente essere eredità. Potrebbe anche essere una qualche forma di delega, per esempio. In effetti, il Trattato di Orlando tratta la delega come alternativa all'eredità e in che modo diverse forme di delega ed eredità portano a diversi punti di progettazione all'interno dello spazio di progettazione di linguaggi orientati agli oggetti. (Si noti che in realtà anche nelle lingue che supportano l'ereditarietà, come Java, alle persone viene effettivamente insegnato ad evitarlo, indicando di nuovo che non è necessario per OO.)