Perché eredità, incapsulamento e polimorfismo non sono i pilastri di OOP? [chiuso]


16

Un giorno sono andato a una chat di Stack Overflow e ho visto una frase che affermava che eredità, incapsulamento e polimorfismo sono i pilastri di OOP (nel senso che sono fondamentali, una suola di costruzione).

Inoltre, c'è una domanda simile, che mi è stata posta molto spesso negli esami universitari e nelle interviste di lavoro, e la risposta giusta è sempre stata la dichiarazione pronunciata nel titolo della domanda ("Sì, eredità, incapsulamento e polimorfismo sono i pilastri di OOP ).

Ma nella chat di Stack Overflow sono stato gravemente ridicolizzato, i partecipanti erano fortemente in disaccordo con una simile affermazione. Quindi, cosa c'è che non va in questa affermazione?

I programmatori sembrano essere addestrati in cose diverse nei college post-sovietici e statunitensi?

Eredità, incapsulamento e polimorfismo non sono considerati i pilastri di OOP dai programmatori USA / Regno Unito?


7
La tua domanda non ha contesto; non sappiamo a cosa stessero pensando le persone nella chat SO o a cosa stessero rispondendo. Forse puoi collegarti alla conversazione nella chat room, quindi possiamo dare un'occhiata? Detto questo, penso che questo sia meglio risolto nella chat room, piuttosto che qui.
Robert Harvey,

1
@Robert, troppe volte. Dubito di riuscire a trovare il collegamento alla conversazione. Ma sono d'accordo che il contesto è importante. Non è da biasimare qualcuno o presentarmi come una vittima innocente di un'aggressione da chat, voglio solo sapere la verità.
PaulD

5
La sala. Prima hai indossato la tua tuta ignifuga?
Robert Harvey,

1
L'unico significato che posso dare alla frase è "puoi avere OOP senza nessuno di loro" (vero, ma non ha senso almeno per l'incapsulamento) o "puoi usarli anche al di fuori di OOP", o qualcosa del genere.
SJuan76,

2
Imo OO ha solo un pilastro e cioè: "Stato". Una volta che il tuo cervello pensa in stato, ottieni OO.
Pieter B,

Risposte:


40

L'ereditarietà, l'incapsulamento e il polimorfismo non sono considerati i pilastri di OOP dai programmatori USA / Regno Unito?

Sono considerati pilastri da molti programmatori e molte università insegnano OO in questo modo.

Sfortunatamente, è anche una visione miope.

  • L'ereditarietà è solo un meccanismo utilizzato per implementare OOP e può essere abusato per non eseguire OOP.
  • L'incapsulamento è un concetto, utile per la programmazione di ogni sorta, OOP e non.
  • Il polimorfismo è un ... tratto (?) Per descrivere come si comporta il calcolo. Esistono molti modi per ottenere il polimorfismo, non tutti specifici per OO.

OOP ha pochissime fondamenta, dal momento che in realtà è molto concettuale: "Approccio alla progettazione del tuo programma pensando alle cose come oggetti - fasci di dati e funzionalità coerenti".

E mentre il moderno design del programma ha una visione scadente del fare le cose in modo "puramente OO", i programmatori più abili concorderanno sul fatto che i principi SOLID (o alcuni sottogruppi) sono candidati migliori per i "pilastri della programmazione orientata agli oggetti" (anche se applicare bene a non OOP). Questi non funzionano affatto con questi termini. Invece usano i concetti di entità software (di cui, gli oggetti sono uno), interfacce (di cui, C # / Java / ecc. interfaceÈ uno), astrazione e sottotitolazione (di cui, l'eredità è una forma).


10
Risposta decente a una domanda essenzialmente senza risposta.
Robert Harvey,

3
OOP esiste?
Tulains Córdova,

5
Direi che solo l'incapsulamento è un "pilastro" di OOP. La più grande differenza tra OOP e la programmazione strutturale è l'idea che gli oggetti contengano codice e dati, non solo dati (ad es. Una classica struttura C). Gli altri due concetti sono utilizzati principalmente nelle lingue OO, ma non sono né limitati a OO né richiesti da esso.

3
L'incapsulamento di @Snowman non è limitato a OOP. Le persone implementano continuamente tipi di dati astratti in linguaggio C e funzionale.
Doval,

2
E @ JörgWMittag ha avuto una buona risposta per quanto riguarda la messaggistica. L'idea della messaggistica richiede necessariamente l' incapsulamento. I messaggi vengono in genere passati a una funzione o un metodo su un oggetto, che agisce quindi sullo stato in esso incapsulato . Ciò non significa che anche le lingue non OO non possano avere passaggi di messaggi o incapsulamenti, ma solo che queste sono idee fondamentali di OOP.

23

tl; dr: puoi avere ereditarietà senza OO, puoi avere incapsulamento senza OO, puoi avere polimorfismo senza OO, puoi persino avere tutti e tre contemporaneamente senza OO. D'altro canto, puoi avere OO senza ereditarietà. Inoltre, ci sono diversi tipi di incapsulamento (orientato all'ADT e OO), IOW non tutto l'incapsulamento è OO.

Versione lunga:

Il termine "Programmazione orientata agli oggetti" è stato inventato da Alan Kay, quindi decide cosa significhi. E lo definisce in questo modo :

OOP per me significa solo messaggistica, conservazione locale, protezione e occultamento del processo statale ed estremo vincolo tardivo di tutte le cose.

Per quanto riguarda l'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.

Punti analoghi vengono anche menzionati 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 stabilire 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.

Ogni programmatore dovrebbe leggere Informazioni sull'astrazione dei dati, rivisitato . Spiega in dettaglio quale sia esattamente la differenza tra oggetti e tipi di dati astratti. Fornisce esempi usando Java, e questo è estremamente rilevante per questa domanda, perché sia negli esempi ADT che negli esempi Object usa ereditarietà, incapsulamento e polimorfismo, ma solo uno degli esempi è orientato agli oggetti! In altre parole: puoi avere ereditarietà, incapsulamento e polimorfismo, puoi persino avere tutti e tre contemporaneamente e non avere ancora OO.

D'altra parte, puoi avere OO senza ereditarietà. Come ho accennato in precedenza: le versioni originali di Smalltalk (il linguaggio progettato da Alan Kay, l'inventore del termine "Programmazione orientata agli oggetti") non avevano eredità.

Infine, ma certamente non meno importante, 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.)


Puoi avere "eredità", "polimorfismo" ed "eredità" ... penso che ci sia un errore di battitura da qualche parte :)
slebetman

1
Questa risposta mi fa desiderare che potremmo anche le risposte "preferite".
Chan-Ho Suh,

La definizione di Alan Kay è obsoleta. OO ha bisogno di ereditarietà e se è possibile eseguire l'associazione sia in fase di esecuzione che in fase di compilazione come in C ++, si ottengono prestazioni alla pari anche con C.
Erik Alapää,

No, la sua definizione è quella corretta. Non hai affatto bisogno dell'eredità per essere OO. I linguaggi prototipo non usano l'ereditarietà come C ++ e sono ancora OO. L'ereditarietà viene utilizzata solo per implementare il riutilizzo del codice, non è nemmeno il modo migliore, ad esempio ci sono molte lingue migliori con mixin. Inoltre non ha nulla a che fare con l'associazione, poiché è possibile disporre del dispacciamento dinamico, nemmeno in C ++ quando è possibile utilizzare metodi virtuali. Le prestazioni non hanno nulla a che fare con questo, sono concetti di alto livello, non hanno prestazioni. In effetti, potresti implementare il passaggio del messaggio in C ed essere OO
Luiz Felipe,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.