Programmazione orientata agli oggetti: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
fix È
mNessun oggetto della modifica
Etichette: Modifica da mobile Modifica da applicazione mobile Modifica da applicazione Android App full source
 
(23 versioni intermedie di 10 utenti non mostrate)
Riga 1:
{{F|programmazione|febbraio 2013}}
{{NN|informatica|gennaio 2024}}
In [[informatica]], la '''programmazione orientata agli oggetti''' (in [[Lingua inglese|inglese]] ''object-oriented programming'', in [[acronimo]] '''OOP'''), a volte chiamata semplicemente '''programmazione ad oggetti''', è un [[paradigma di programmazione]] che permette di definire [[Oggetto (informatica)|oggetti]] [[software]] in grado di interagire gli uni con gli altri attraverso lo scambio di messaggi. È particolarmente adatta nei contesti in cui si possono definire delle relazioni di interdipendenza tra i concetti da modellare (contenimento, uso, specializzazione). Un ambito che più di altri riesce a sfruttare i vantaggi della programmazione a oggetti è quello delle [[Interfaccia grafica|interfacce grafiche]].
 
In [[informatica]], la '''programmazione orientata agli oggetti''' (in [[Lingua inglese{{Inglese|inglese]] ''object-oriented programming''}}, in [[acronimo]] '''OOP'''), a volte chiamata semplicemente '''programmazione ada oggetti''', è un [[paradigma di programmazione]] che permette di definire [[Oggetto (informatica)|oggetti]] [[software]] in grado di interagire gli uni con gli altri attraverso lo scambio di messaggi. È particolarmente adatta nei contesti in cui si possono definire delle relazioni di interdipendenza tra i concetti da modellare (contenimento, uso, specializzazione). Un ambito che più di altri riesce a sfruttare i vantaggi della programmazione a oggetti è quello delle [[Interfaccia grafica|interfacce grafiche]].
 
Per "scambio di messaggi" s'intende la capacità degli oggetti di chiamare i metodi pubblici di altri oggetti, per esempio passandogli dati da elaborare e ricevendo il risultato della loro elaborazione. La OOP è particolarmente adatta nei contesti in cui si possono definire delle relazioni di interdipendenza tra i concetti da modellare (contenimento, uso, specializzazione). Un ambito che più di altri riesce a sfruttare i vantaggi della programmazione a oggetti è quello delle [[Interfaccia grafica|interfacce grafiche]].
 
Tra gli altri vantaggi della programmazione orientata agli oggetti:
* essa fornisce un supporto naturale alla modellazione [[software]] degli oggetti del mondo reale o del modello astratto da riprodurre;
* permette una più facile gestione e manutenzione di progetti di grandi dimensioni;
* l'organizzazione del [[codice sorgente|codice]] sotto forma di [[Classe (informatica)|classi]] favorisce la [[Modularità (informatica)|modularità]] e il [[riuso di codice]].
 
== Storia ==
Il concetto di ''classe'' può essere considerato un'estensione di quello di [[tipo di dato astratto]], sviluppatosi inizialmente all'interno del paradigma della [[programmazione procedurale]], che prevede la definizione da parte del programmatore di [[tipi di dato]] con cui si può interagire solo attraverso una [[interfaccia (informatica)|interfaccia]] ben definita, nascondendo all'utilizzatore i dettagli dell'implementazione.<br />
I costrutti sintattici che permettono di definire una classe, nei linguaggi a oggetti, possono essere visti come un supporto strutturato per realizzare i dati astratti.
 
Il primo linguaggio di programmazione orientato agli oggetti fu il [[Simula]] ([[1967]]), seguito negli [[Anni 1970|anni settanta]] da [[Smalltalk]] e da varie estensioni del [[Lisp]]. Negli [[Anni 1980|anni ottanta]] sono state create estensioni orientate ada oggetti del [[C (linguaggio)|linguaggio C]] ([[C++]], [[Objective-C]] e altri), e di altri linguaggi ([[Object Pascal]]). Negli [[Anni 1990|anni novanta]] quello ada oggetti è diventato il paradigma dominante, per cui gran parte dei linguaggi di programmazione erano o nativamente orientati agli oggetti o avevano una estensione in tal senso.
Linguaggi che supportano solo il paradigma di programmazione orientata agli oggetti sono Smalltalk ed [[Eiffel (linguaggio)|Eiffel]].
Più spesso si incontra una realizzazione non esclusiva del paradigma di programmazione orientata agli oggetti, come in [[C++]], [[Java (linguaggio di programmazione)|Java]], [[Delphi]], [[Python]], [[C sharp|C#]], [[Visual Basic .NET]], [[Perl]], [[PHP]] (a partire dalla versione 4).
 
== Descrizione ==
La programmazione ada oggetti prevede di raggruppare in alcune parti circoscritte del [[codice sorgente]], chiamate ''[[#Classi|classi]]'', la dichiarazione delle [[struttura dati|strutture dati]] e delle [[funzione (informatica)|procedure]] che operano su di esse. Le classi, quindi, costituiscono dei modelli astratti, che a [[Run-time|tempo di esecuzione]] vengono invocate per istanziare o creare [[#Oggetti|oggetti]] software relativi alla classe invocata. Questi ultimi sono dotati di ''attributi'' (dati) e ''[[Metodo (programmazione)|metodi]]'' (procedure) secondo quanto definito/dichiarato dalle rispettive classi.
 
La parte del programma che fa uso di un oggetto si chiama ''client''.
 
Un linguaggio di programmazione è definito ''ada oggetti'' quando permette di implementare trequattro meccanismi usando la sintassi nativa del linguaggio<ref>Questi meccanismi possono essere simulati anche nei linguaggi che non sono considerati ad oggetti, a patto di adottare altri costrutti e di rispettare determinate convenzioni durante la scrittura del testo del programma.</ref>:
L<nowiki>'</nowiki>'''* [[#Incapsulamento|incapsulamento''']]: consiste nella separazione della cosiddetta [[Interfaccia (informatica)#Interfaccia nella programmazione orientata agli oggetti|interfaccia]] di una classe dalla corrispondente implementazione, in modo che i client di un oggetto di quella classe possano utilizzare la prima, ma non la seconda.
* [[#Incapsulamento|incapsulamento]];
* [[#Ereditarietà|ereditarietà]];: permette essenzialmente di definire delle classi a partire da altre già definite.
Il* '''[[#Polimorfismo|polimorfismo''']]: permette di scrivere un client che può servirsi di oggetti di classi diverse, ma dotati di una stessa [[Interfaccia (informatica)#Interfaccia nella programmazione orientata agli oggetti|interfaccia]] comune; nel tempo di esecuzione tale client potrà attivare comportamenti diversi senza conoscere a priori il tipo specifico dell'oggetto che gli viene dato in ingresso.
* [[#Polimorfismo|polimorfismo]].
* Astrazione: Si tratta del processo di identificazione degli aspetti essenziali di una forma o concetto, astratti dalle specifiche realizzazioni. In OOP, significa definire le interfacce separate dalle implementazioni, consentendo al programmatore di lavorare con concetti ad alto livello senza preoccuparsi dei dettagli.
 
L<nowiki>'</nowiki>'''incapsulamento''' consiste nella separazione della cosiddetta [[Interfaccia (informatica)#Interfaccia nella programmazione orientata agli oggetti|interfaccia]] di una classe dalla corrispondente implementazione, in modo che i client di un oggetto di quella classe possano utilizzare la prima, ma non la seconda.
 
L<nowiki>'</nowiki>'''ereditarietà''' permette essenzialmente di definire delle classi a partire da altre già definite.
 
Il '''polimorfismo''' permette di scrivere un client che può servirsi di oggetti di classi diverse, ma dotati di una stessa [[Interfaccia (informatica)#Interfaccia nella programmazione orientata agli oggetti|interfaccia]] comune; nel tempo di esecuzione tale client potrà attivare comportamenti diversi senza conoscere a priori il tipo specifico dell'oggetto che gli viene dato in ingresso.
 
=== Classi ===
Riga 36 ⟶ 35:
 
La classe è composta da:
* ''attributi'' (analoghi ai membri di un [[Struttura dati#Record o struttura|record]]), ossia [[variabile (informatica)|variabili]] e/o [[costante (informatica)|costanti]] che definiscono le caratteristiche o proprietà degli oggetti instanziabiliistanziabili invocando la classe; i valori inizializzati degli attributi sono ottenuti attraverso il cosiddetto [[Costruttore (informatica)|costruttore]];
* ''metodi'', ossia [[funzione (informatica)|procedure]] che operano sugli attributi.
 
Un paragone (impreciso) con la [[matematica]] è il seguente: si può pensare che una classe definisca un [[insieme]] in modo intensivo, ovvero indicandone le caratteristiche invece che elencandone gli elementi, e che gli oggetti siano gli elementi di quell'insieme. Tuttavia, in matematica, il [[cardinalità|numero degli elementi]] è una caratteristica intrinseca dell'insieme stesso, e risulta definito nel momento in cui si definisce l'insieme, mentre in programmazione è possibile istanziare una classe un numero di volte arbitrario (teoricamente da zero ada infinito, in pratica da zero fino a esaurimento della [[RAM|memoria di lavoro]] del calcolatore) e che dipende dall'esecuzione del programma. Per questo motivo, è preferibile considerare la classe come un modello astratto istanziabile.
 
In altri termini, una classe è paragonabile al [[progetto]] di un'[[infrastruttura]] che può poi essere messa in opera/esercizio ovvero realizzata o meno con l'istanziazione dei suoi oggetti tutti con le medesime caratteristiche, ovvero gli attributi (con valori diversi), su cui opereranno i metodi o funzioni.
Riga 45 ⟶ 44:
=== Oggetti ===
{{vedi anche|Oggetto (informatica)}}
Un oggetto è una istanza di una classe. Esso è dotato di tutti gli attributi e i metodi definiti dalla classe, ede agisce come un fornitore di "messaggi" (i metodi) che il codice eseguibile del programma (procedure o altri oggetti) può attivare su richiesta.<br />
Inviare un messaggio ada un oggetto significa, in gergo, invocare un metodo su quell'oggetto. Il metodo riceve come parametro (spesso implicito) l'oggetto su cui è stato invocato, che può essere referenziato tramite una parola-chiave o una sintassi apposita, anche se è passato come parametro implicito; per esempio, in [[C++]], in [[Java (linguaggio di programmazione)|Java]], e in [[C sharp|C#]] si usa la [[Parola riservata|parola- chiave]] <code>this</code> (<code>{{Codice|codice=$this</code>|linguaggio=PHP}} in PHP), mentre in [[Smalltalk]], in [[Objective C|Objective-C]], [[Python]] e in [[Ruby (linguaggio di programmazione)|Ruby]] si usa la parola- chiave <code>self</code>.
 
Dal punto di vista del calcolatore, ogni oggetto è identificato da una certa [[memoria RAM|zona di memoria]], nella quale sono memorizzati gli ''[[Attributo (programmazione)|attributi]]'', e il valore di questi ultimi determina lo stato interno dell'oggetto. ''Istanziare'' un oggetto vuol dire [[allocazioneAllocazione dinamica della memoria|allocare]] memoria ed eventualmente inizializzarla secondo le specifiche definite dalla classe. Molti linguaggi forniscono un supporto per l'inizializzazione automatica di un oggetto, con uno o più metodi speciali, detti ''[[Costruttore (informatica)|costruttori]]''. Analogamente, la fine della vita di un oggetto può essere gestita con un metodo detto ''[[distruttoreDistruttore (informatica)|distruttore]]''.
 
Il codice eseguibile del programma accede a tale zona di memoria sempre e solo secondo le modalità definite dalla classe.<br />
Secondo il principio noto come ''[[#Incapsulamento|information hiding]]'', l'accesso ai campi di un oggetto deve essere permesso solo tramite metodi invocati su quello stesso oggetto. Il vantaggio principale è che il controllo completo sullo stato interno viene assegnato ada una zona ristretta del codice eseguibile del programma (la classe), perché il codice esterno non è autorizzato a modificarlo. In tal caso, risulta possibile imporre dei vincoli sui possibili valori che la [[tupla]] degli attributi può o non può assumere, e anche sulle possibili transizioni tra questi stati. Un oggetto quindi può essere visto come una [[Automa a stati finiti|macchina a stati finiti]].
 
== Incapsulamento ==
{{Vedi anche|Incapsulamento (informatica)}}
L<nowiki>'</nowiki>''incapsulamento'' è la proprietà per cui i dati che definiscono lo stato interno di un oggetto e i metodi che ne definiscono la logica sono accessibili ai metodi dell'oggetto stesso, mentre non sono visibili ai client. Per alterare lo stato interno dell'oggetto, è necessario invocarne i metodi pubblici, ed è questo lo scopo principale dell'incapsulamento. Infatti, se gestito opportunamente, esso permette di vedere l'oggetto come una ''[[Modello black box|black-box]]'', cioè una "scatola nera" con la quale l'interazione avviene solo e solamente tramite i metodi definiti dall'interfaccia. Il punto è dare delle funzionalità agli utenti nascondendo i dettagli legati alla loro implementazione. Un esempio potrebbe essere un oggetto "matematica" che, tra le tante operazioni che fornisce, cene n'èha una che moltiplica due numeri. Per esempio <kbdcode>moltiplica(2,3)</kbdcode> restituisce 6. Adesso lL'algoritmo di moltiplicazione può essere uno dei tanti algoritmi che esistonoesistenti, però questo per chi chiama il metodo <kbdcode>moltiplica()</kbdcode> non fa nessuna differenza. L'importante è che il risultato non sia errato.
 
== Ereditarietà ==
{{Vedi anche|Ereditarietà (informatica)}}
Il meccanismo dell<nowiki>'</nowiki>''[[Ereditarietà (informatica)|ereditarietà]]'' è utilizzato in fase di strutturazione/definizione/pianificazione del software o in successive estensioni e permette di derivare nuove classi a partire da quelle già definite realizzando una gerarchia di classi. Una classe derivata attraverso l'ereditarietà (''[[Sottoclasse (informatica)|sottoclasse'']] o classe figlia) mantiene i metodi e gli attributi delle classi da cui deriva (''classi base'', ''superclassi'' o classi madre); inoltre, può definire i propri metodi o attributi, e ridefinire il codice di alcuni dei metodi ereditati tramite un meccanismo chiamato ''[[overriding]]''.
 
Quando una classe eredita da una sola superclasse si parla di eredità singola; viceversa, si parla di eredità multipla. Alcuni linguaggi (tra gli altri, Java, Smalltalk) forniscono supporto esclusivo all'ereditarietà singola. Altri (C++, Python) prevedono anche l'ereditarietà multipla.
Riga 68 ⟶ 67:
 
; Esempio
Se nel programma esiste già una classe <kbdcode>MezzoDiTrasporto</kbdcode> che ha come proprietà i dati di posizione, velocità, destinazione e carico utile, e occorre una nuova classe <kbdcode>Aereo</kbdcode>, è possibile crearla direttamente dall'oggetto <kbdcode>MezzoDiTrasporto</kbdcode> dichiarando una classe di tipo <kbdcode>Aereo</kbdcode> che eredita da <kbdcode>MezzoDiTrasporto</kbdcode> e aggiungendovi anche l'attributo che identifica la [[quota di crociera]], con il vantaggio che la nuova classe acquisirà tutti i membri definiti in <kbdcode>MezzoDiTrasporto</kbdcode> per il fatto stesso di esserne sottoclasse.
 
=== Sottotipizzazione ===
{{vedi anche|Sottotipo (informatica)}}
Sebbene concettualmente esistano delle differenze ben marcate, il meccanismo di eredità fra classi (''subclassing''), attraverso il meccanismo del polimorfismo per inclusione, permette nei linguaggi ada oggetti di modellare l'eredità fra tipi (''subtyping'').
 
Secondo il [[principio di sostituzione di Liskov]], un tipo <kbdcode>S</kbdcode> è un ''sottotipo'' di <kbdcode>T</kbdcode> quando è possibile sostituire tutte le istanze di <kbdcode>T</kbdcode> con delle istanze di <kbdcode>S</kbdcode> mantenendo intatto il funzionamento del programma.
 
Con gli opportuni accorgimenti è possibile creare una relazione di classe-sottoclasse che rispetti anche i vincoli della relazione tipo-sottotipo. Da un punto di vista sintattico, ciò richiede che tutti i metodi della superclasse siano presenti nella sottoclasse, e che le rispettive ''[[Firma (programmazione)|signature]]''firme siano compatibili. Di conseguenza, una sottoclasse che voglia definire un sottotipo può ridefinire i metodi della superclasse, ma non può eliminarli. La ''signature''firma dei metodi può essere solo parzialmente modificata, rispettando dei vincoli sulla variazione dei parametri rispetto alla catena di eredità.
 
Tuttavia, il rispetto delle restrizioni sintattiche non è sufficiente, da solo, ad assicurare il rispetto della condizione di Liskov: la [[overriding|ridefinizione dei metodi]] o la {{chiarire|riassegnazione degli attributi}}, infatti, potrebbe compromettere la compatibilità in tempo di esecuzione.
 
In molti linguaggi, nella definizione di una sottoclasse, si può decidere di eliminare o cambiare le proprietà di accesso a un metodo ereditato. In tal caso, l'operazione di ''subclassing'' non corrisponde a quella di ''subtyping''. Alcuni linguaggi a oggetti, in particolare [[Sather]], dividono esplicitamente a livello sintattico ''subclassing'' e ''subtyping''.
 
In linguaggi con [[tipizzazione statica]] ed [[tipizzazione esplicita|esplicita]], la sottotipizzazione viene supportata attraverso il polimorfismo per inclusione delle sottoclassi: una stessa variabile può fare riferimento ada un oggetto del tipo per cui è stata dichiarata, o di tipi da esso derivati. Il tipo dell'oggetto individuato dalla variabile, quindi, viene definito a ''[[runtime]]'' ([[binding dinamico]]), e può essere modificato durante l'esecuzione del programma.
 
== Polimorfismo ==
{{Vedi anche|Polimorfismo (informatica)}}
Nella programmazione ada oggetti, con il nome di polimorfismo per inclusione, si indica il fatto che lo stesso codice eseguibile può essere utilizzato con istanze di classi diverse, aventi una ''superclasse'' comune.
 
=== Binding dinamico o polimorfismo orizzontale ===
{{vedi anche|Binding}}
Il [[polimorfismo (informatica)|polimorfismo]] è particolarmente utile quando la versione del metodo da eseguire viene scelta sulla base del tipo di oggetto effettivamente contenuto in una variabile a ''runtime'' (invece che al momento della [[compilatore|compilazione]]). Questa funzionalità è detta ''[[Binding|binding dinamico]]'' dinamico (o ''late-binding''), ed è supportato dai più diffusi linguaggi di programmazione ada oggetti.
 
Se una variabile di tipo <kbdcode>A</kbdcode> ha due sottotipi (sottoclassi) <kbdcode>B</kbdcode> e <kbdcode>C</kbdcode>, che ridefiniscono entrambe il metodo <kbdcode>m()</kbdcode>, l'oggetto contenuto nella variabile potrà essere di tipo <kbdcode>A</kbdcode>, <kbdcode>B</kbdcode> o <kbdcode>C</kbdcode>, e quando sulla variabile viene invocato il metodo <kbdcode>m()</kbdcode> viene eseguita la versione appropriata per il tipo di oggetto contenuto nella variabile in quel momento.
 
Per ritornare all'esempio precedente, si suppone che un <kbdcode>Aereo</kbdcode> debba affrontare procedure per l'arrivo e la partenza molto più complesse di quelle di un normale camion, come in effetti è: allora le procedure <kbdcode>arrivo()</kbdcode> e <kbdcode>partenza()</kbdcode> devono essere cambiate rispetto a quelle della classe base <kbdcode>MezzoDiTrasporto</kbdcode>. Si provvede quindi a ridefinirle nella classe <kbdcode>Aereo</kbdcode> in modo da ottenere il comportamento necessario (polimorfismo): a questo punto, dalla lista di mezzi è possibile prendere qualsiasi mezzo e chiamare <kbdcode>arrivo()</kbdcode> o <kbdcode>partenza()</kbdcode> senza più doversi preoccupare di che cos'è l'oggetto che si sta maneggiando: che sia un mezzo normale o un aereo, si comporterà rispondendo alla stessa chiamata sempre nel modo giusto.
 
Il supporto al ''binding dinamico'' dinamico non è necessariamente automatico in tutti i linguaggi di programmazione ada oggetti. Ad esempio in Java, Smalltalk, Python, Ruby, il ''binding dinamico'' è implicitamente usato come comportamento di default nelle classi polimorfe, mentre in C++ viene abilitato inserendo la keywordparola ''riservata {{Codice|codice=virtual''|linguaggio=C++}} nella signature[[Firma (programmazione)|firma]] del metodo interessato.
 
Il supporto ''runtime'' di una chiamata di metodo polimorfa richiede che a una variabile polimorfa venga associato un [[metadato]] implicito che contiene il tipo del dato contenuto nella variabile in un dato momento, oppure la tabella delle funzioni polimorfe.
 
==== Esempio - Binding dinamico ====
Si supponga di avere il seguente pseudo codice in Java dove <kbdcode>Classe2</kbdcode> è una sottoclasse di <kbdcode>Classe1</kbdcode>:
<syntaxhighlight lang="java" line="1">
void metodo(int input) {
Classe1 c;
Riga 115 ⟶ 114:
</syntaxhighlight>
 
Si noti che <kbdcode>faiQualcosaDiImportante</kbdcode> è un metodo definito da <kbdcode>Classe1</kbdcode> ma potrebbe essere stato ridefinito in <kbdcode>Classe2</kbdcode> (perché magari deve essere stampato in maniera diversa). Il compilatore non può sapere a tempo di compilazione se <kbdcode>c</kbdcode> è un oggetto associato alla classe <kbdcode>Classe1</kbdcode> o <kbdcode>Classe2</kbdcode>. Tramite il binding dinamico la scelta su quale metodo effettivamente ''linkare'' sarà effettuata durante l'esecuzione (''runtime''), quando il metodo viene effettivamente chiamato.
 
=== Polimorfismo verticale ===
Riga 124 ⟶ 123:
Alcuni meccanismi inclusi nella gestione degli oggetti causano un overhead in termini di tempo e memoria, che in determinate situazioni può portare a problemi di efficienza.
 
Alcuni linguaggi come [[Java (linguaggio di programmazione)|Java]] e [[C++]] preferiscono un approccio ibrido rispetto all'OOP "puro", ad esempio del linguaggio [[Smalltalk]], prevedendo che alcuni tipi di dati primitivi non siano considerati come oggetti. I vantaggi di quest'approccio sono particolarmente evidenti in presenza di computazioni numeriche; di contro, ogni volta che è necessario un oggetto in luogo di un tipo primitivo è necessario ricorrere ada un apposito ''wrapper'', e questo può portare a cali prestazionali.
 
Tale wrapper può anche essere dato automaticamente dal linguaggio stesso, come nel caso del Java o del [[C sharp|C#]], tramite una conversione automatica chiamata "''autoboxing"'' (inscatolamento automatico). Essa permette di mettere valori di tipi primitivi (es.— per esempio interi, o caratteri) all'interno di oggetti, quindi di richiamare parti di codice che vorrebbero oggetti senza scrivere esplicitamente l'istruzione di creazione dell'oggetto che racchiude il valore. Tale inscatolamento risolve il problema di scrivere un ''wrapper'' a mano, ma ovviamente il calo di prestazioni rimane.
 
Altre critiche all'OOP riguardano la maggiore complessità strutturale rispetto ai linguaggi procedurali, a fronte delle limitazioni introdotte per seguire il paradigma a oggetti. Esistono inoltre alcune carenze concettuali (in particolare riguardo alla sottotipizzazione), che aggiunte alle diverse implementazioni nei linguaggi possono causare problemi al programmatore. Ad esempio il funzionamento in contesti polimorfi non è garantito quando i metodi vengano ridefiniti in una catena di eredità. Inoltre cambiare le definizioni nelle classi base può portare a introdurre errori in cascata nelle sottoclassi ([[problema della classe base fragile]]).
Riga 134 ⟶ 133:
 
== Bibliografia ==
* {{cita pubblicazione
|titolo = What is ‘‘Object-Oriented Programming’’? (1991 revised version)
|autore = [[Bjarne Stroustrup]]
|url = https://stroustrup.com/whatis.pdf
|editore = AT&T [[Bell Laboratories]]
|città = Murray Hill
|data = 1991
|lingua = en
}}
* {{RivistaVG|mc|101|272-275|11|1990|titolo=Introduzione alla programmazione orientata all'oggetto - Prima parte}}
* {{RivistaVG|mc|102|241-245|12|1990|titolo=Introduzione alla programmazione orientata all'oggetto - Seconda parte}}
Riga 144 ⟶ 152:
* [[Copia di un oggetto]]
* [[Unified Modeling Language]]
 
== Altri progetti ==
{{Interprogetto|preposizione=sulla}}
 
== Collegamenti esterni ==
* {{Collegamenti esterni}}
* {{FOLDOC|object-oriented programming|object-oriented programming}}
* {{cita web|http://www.bluej.org|bluej: Ambiente di sviluppo open source per l'insegnamento della programmazione ad oggetti (in Java)}}
* {{cita web
* [https://www.html.it/guide/guida-programmazione-orientata-agli-oggetti/ Guida programmazione orientata agli oggetti] La guida, oltre a fornire la teoria di base della OOP, è ricca di esempi pratici in tutti i linguaggi più usati dagli sviluppatori web: da C# a Actionscript, fino a Java e Python.
|url=https://www.html.it/guide/guida-programmazione-orientata-agli-oggetti/
|titolo = Guida programmazione orientata agli oggetti
|autore = Marco Altese
|anno = 2006
}}
 
{{Paradigmi di programmazione}}