Quali sono le funzionalità richieste per l'orientamento agli oggetti?


9

Mi chiedo solo quali sono esattamente le caratteristiche che una lingua o una libreria deve fornire per poter essere definita come "orientata agli oggetti". L'orientamento agli oggetti è qualcosa che può, più o meno, essere raggiunto in qualsiasi linguaggio di programmazione generico con funzionalità decenti? O è qualcosa che può essere raggiunto solo in linguaggi che pubblicizzano specificamente che supportano la programmazione orientata agli oggetti?

Ad esempio, guarda il seguente codice C:

SDL_Surface* screen = SDL_SetVideoMode( 640, 480, 16, SDL_HWSURFACE);
SDL_FreeSurface( screen );

o il codice discusso qui .

Ora il codice sopra non usa ereditarietà, runtime-polimorfismo (?), Funzioni virtuali ecc. Ma a me sembra praticamente OOP.

L'orientamento agli oggetti sta semplicemente scrivendo codice che si basa su strutture di dati creabili e distruttibili come oggetti, classi, strutture ecc. Che non richiedono alcun modello o funzionalità speciali forniti dal linguaggio di programmazione o da una libreria ?


2
OOP richiede generalmente oggetti . Tuttavia è possibile scrivere codice che sembra OOP nella maggior parte delle lingue (dubito che si possa dire "questo assembly sembra OOP")
Raynos

Il codice sopra riportato non utilizza un'istruzione if o un ciclo . Non utilizza la moltiplicazione o l'aggiunta. Non puoi usare due righe di codice e un elenco di cose non mostrate per dare un giudizio. Da quelle due righe di codice, potrei dedurre che è un linguaggio di programmazione funzionale rigorosamente pigro, non un linguaggio OO. L'uso di due righe di codice come parte di una generalizzazione non è una vera domanda.
S.

Il link è anche incluso nel codice sopra che ho giudicato. Nota anche che non è un giudizio , ti sto chiedendo se questo potrebbe essere considerato OOP.
ApprenticeHacker

La banale risposta è . Il mio punto è questo. Da esempi di codice non è possibile esprimere un giudizio su OOP. È una banale questione di definizione. O la lingua è definita come una lingua OOP o non lo è. Eventuali esempi di codice potrebbero non richiedere tutte le funzionalità OOP. In effetti, il codice OOP può usare pochissime funzionalità. In Python, ad esempio, 1+2è davvero orientato agli oggetti. È un costruttore che costruisce un nuovo oggetto da due oggetti esistenti. L'uso di esempi di codice non rivela nulla.
S.

Cosa c'è di sbagliato nell'usare questa definizione e nel confrontarla con la lingua (non con due esempi di codice)? en.wikipedia.org/wiki/…
S.Lott

Risposte:


11

Secondo Alan Kay, che ha inventato il termine "orientato agli oggetti",

OOP per me significa solo messaggistica, conservazione locale, protezione e occultamento del processo statale ed estremo vincolo tardivo di tutte le cose. Può essere fatto in Smalltalk e in LISP. Probabilmente ci sono altri sistemi in cui ciò è possibile, ma non ne sono consapevole.

La messaggistica (come implementata in Smalltalk) è un concetto paragonabile al polimorfismo, ma piuttosto più potente (almeno rispetto al tipo di polimorfismo supportato da C ++ o Java). Può essere fatto in tutte le lingue, ma è piuttosto doloroso se non supportato direttamente dalla lingua. Fondamentalmente significa che gli oggetti possono scambiarsi messaggi contenenti qualsiasi cosa, e possono reagire come vogliono ai messaggi che ricevono. Per supportare completamente la messaggistica, ci deve essere un modo per gli oggetti di reagire in modo flessibile ai messaggi senza elencarli nel codice sorgente (che è fondamentalmente ciò che fanno le definizioni di metodo / funzione).

la conservazione e la protezione locali e il nascondimento del processo statale - incapsulamento dell'AKA - possono essere fatti per convenzione in tutte le lingue, ma ciò in qualche modo tradisce. La conservazione locale a livello di lingua sembra in realtà essere l'unica caratteristica che condividono tutte le lingue che dichiarano di essere OO (e molte che non lo fanno) - c'è generalmente un modo per creare tipi di dati composti con più istanze. La protezione e il nascondiglio, d'altra parte, sono spesso fatti solo per convenzione.

associazione tardiva di tutte le cose - una scala mobile su cui C è davvero molto lontano dalla visione di Kay (come C ++, mentre Java è molto più vicino). Può essere falso (vedi COM), ma sarà un dolore da usare.

Nota come Kay non menziona l' eredità . Nella stessa email ha scritto

Non mi piaceva il modo in cui Simula I o Simula 67 avevano ereditato (anche se pensavo che Nygaard e Dahl fossero solo grandi pensatori e designer). Così ho deciso di escludere l'eredità come funzionalità integrata fino a quando non ho capito meglio


4
In che modo Java e C # sono più vicini al late-binding rispetto al C ++?
Fredoverflow

@FredOverflow: Java carica pigramente le definizioni delle classi in fase di runtime quando vengono utilizzate per la prima volta, e lo fa implicitamente tramite un meccanismo estremamente flessibile che consente facilmente di aggiungere nuove classi o addirittura di generarle al volo. C ++ richiede di ricollegare l'eseguibile o caricare esplicitamente le librerie. La situazione con C # sembra essere meno chiara di quanto pensassi, quindi ho rimosso il riferimento a ti.
Michael Borgwardt,

5

La programmazione orientata agli oggetti non riguarda le funzioni di sintassi, è una filosofia di codifica e progettazione. Alla base c'è il concetto di un oggetto , che è un costrutto che i gruppi dichiarano con routine per agire su di esso (o, a seconda del punto di vista, delle risposte ai messaggi). L'altro aspetto importante di OOP è l' incapsulamento : avvolgere i dettagli di implementazione in strutture opache e collegarli attraverso interfacce ben definite. Praticamente tutto il resto nella teoria OOP risale a questi due fondamenti.

Quindi, qualsiasi linguaggio che può in qualche modo modellare oggetti (entità che contengono sia dati che codice) e incapsulamento può essere usato per fare OOP. Ad esempio, in C è possibile utilizzare i puntatori a funzione per memorizzare le funzioni nelle strutture e è possibile utilizzare il file system di intestazione / sorgente per realizzare l'incapsulamento. Non è conveniente, ma è sufficiente fare OOP. Probabilmente puoi anche piegare qualcosa come Haskell o ML nel fare OOP, e non sarei sorpreso se qualcuno potesse escogitare un modo di fare OOP in assemblea.

In pratica, tuttavia, un linguaggio può essere definito "orientato agli oggetti" se fornisce un set completo di funzioni di sintassi per la programmazione esplicita orientata agli oggetti. In genere, ciò significa che un tale linguaggio dovrebbe avere: * una nozione di oggetto * una nozione di metodo di chiamata o passaggio di messaggi * un modo comodo e diretto di controllare l'accesso ai membri dell'oggetto * un modo comodo e semplice di definire le interfacce

Di conseguenza, definirei un pezzo di codice orientato agli oggetti se aderisce ai principi OOP e utilizza la sintassi OOP disponibile.

BTW., Il tuo esempio di codice probabilmente fa uso il polimorfismo e funzioni virtuali, anche se la sintassi C non lo rende evidente. Non sono un esperto di SDL, ma mi aspetto SDL_surfacedi essere in grado di rappresentare vari tipi di superfici, ognuna con il proprio set specifico di implementazioni: la fusione di qualcosa su una bitmap di memoria e la fusione su una superficie dello schermo richiedono radicalmente differenti codice, ma l'interfaccia (le funzioni che accettano SDL_surface*come argomento) rimane la stessa. Proprio così, implementa anche l'incapsulamento: non puoi accedere direttamente alla rappresentazione sottostante di una superficie, devi passare attraverso funzioni che sanno come gestire un SDL_surface, perché è tutto ciò che hai. È un bell'esempio di come faresti OOP in C.


Tuttavia, i tipi di dati astratti, la modellazione e l'incapsulamento dei dati non sono univoci per OO (come menzionerai brevemente te stesso). Preferirei descrivere OO in base alle sue caratteristiche più uniche (associazione dinamica di chiamate di metodo, polimorfismo tramite tali chiamate di metodo, ecc.)
hugomg

4

La mia comprensione di OO è che OO è un modo di pensare e un'implementazione che si basa sull'idea che un compito computazionale può essere realizzato da un lavoratore (oggetto) o dalla collaborazione di singoli lavoratori (oggetti) tramite un messaggio che passa tra quei lavoratori ( oggetti) in fase di esecuzione. Questo comportamento di runtime richiede solidi costrutti statici e dinamici per abilitarlo.

La sintassi specifica per implementare OO non è la chiave che determina se una lingua è OO o meno. Ad esempio, Smalltalk e C # hanno sintassi diverse ma entrambi sono linguaggi OO (a vari livelli). La chiave è se il linguaggio dato conserva la filosofia (sopra) e fornisce i mezzi di impianto richiesti.


2

Quando ero uno studente mi hanno insegnato che la programmazione orientata agli oggetti si basa su tre pilastri:

  • incapsulamento ,
  • polimorfismo e
  • eredità .

Un linguaggio dovrà supportare tali funzionalità per essere considerato un linguaggio orientato agli oggetti.

Si noti che questo descrive una serie di funzionalità, piuttosto che la sintassi . Quindi, se devi scrivere

type obj; // or type obj = new type;
obj.func(arg);

o

type* ptr = create_type();
func(ptr, arg); 

non importa.

Quindi puoi davvero programmare secondo il paradigma orientato agli oggetti in C. Ma il linguaggio non offre supporto per questo, il che lo rende un esercizio piuttosto doloroso. Questo è il motivo per cui C non è considerato un linguaggio orientato agli oggetti.


2
Insegnare a questi "pilastri" ha probabilmente fatto più male che bene al mondo. L'incapsulamento è buono, ma questo è tutto.
martedì

1
Sono in questo elenco, quindi sembrano essere ampiamente accettati: en.wikipedia.org/wiki/…
S.Lott

Puoi spiegare perché il polimorfismo e l'ereditarietà sono cattivi?
MathAttack

@MathAttack: stai parlando con me? Perché di certo non l'ho detto.
sabato

1
@missingno: qualcosa non deve essere unico per alcuni paradigmi per essere considerato importante per distinguere il paradigma. L'incapsulamento non deve più essere unico per OOP poiché le funzioni devono essere uniche per la programmazione strutturata.
sabato

2

È possibile fare OO in qualsiasi lingua general-purpose decente.

È più facile farlo in un linguaggio "OO", perché hai costrutti idiomatici disponibili e non devi ricorrere a qualcosa come OO in C - che è possibile, ma orribile.

Che i costrutti OO siano forniti dal linguaggio stesso, dalla sua libreria standard o da qualche altra libreria, non importa molto, poiché alcuni linguaggi (ad esempio Scala) consentono alle biblioteche di aggiungere costrutti linguistici in modo che dal punto di vista del programmatore sia quasi impossibile per distinguere quali cose sono fornite dal linguaggio principale e quali da una biblioteca.


2

Se si guarda alla gamma di lingue che sono state ampiamente accettate come OO e quelle che non lo hanno fatto, il test sembra essere il supporto per il polimorfismo dell'inclusione (alias polimorfismo di sottotipo, ma il polimorfismo dell'inclusione è il termine usato da Cardelli nel articolo che mi ha fatto conoscere, e ne penso molti altri, una classificazione dei tipi di polimorfismo). Vale a dire la possibilità che alcune variabili abbiano valori di tipi diversi e la possibilità che alcune chiamate inviino a routine diverse a seconda del tipo di uno o più valori. Tutto il resto è stato presente in lingue non accettate come OO o mancanti da lingue ben accettate come OO.

Le altre due principali caratteristiche associate alle lingue OO sono state fornite da lingue non OO:

  • L'incapsulamento è abbastanza ben fornito da Ada83;
  • L'ereditarietà è fornita da Oberon (Oberon è interessante, Wirth voleva fornire un linguaggio OO con il minor numero possibile di cruft, ma ha dovuto rivisitare la sua concezione per ottenerne uno - Oberon-2 è OO).

1

L'orientamento agli oggetti è definito come

controlla anche le voci di Wikipedia. queste sono le caratteristiche che un linguaggio deve fornire per essere definito orientato agli oggetti.

considera il tuo codice orientato agli oggetti se è in un linguaggio di programmazione orientato agli oggetti. anche se scrivi qualcosa che sembra essere procedurale, agirà su metodi in oggetti di classi usando il polimorfismo attraverso l'incapsulamento [forse] :)

per quanto riguarda la tua ultima domanda, la risposta è probabilmente. sì. orientato agli oggetti è fondamentalmente semplicemente agire su metodi su oggetti e passare tali oggetti come parametri.


3
Definito da chi?
Michael Borgwardt,
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.