Domanda

Poiché il dibattito senza termini significativi lo è senza senso, ho pensato di indicare l'elefante nella stanza e chiedere:Cosa rende esattamente un linguaggio "orientato agli oggetti"?Non sto cercando una risposta da un libro di testo qui, ma una risposta basata sulle tue esperienze con i linguaggi OO che funzionano bene nel tuo dominio, qualunque esso sia.

Una domanda correlata a cui potrebbe essere utile rispondere prima è:Qual è l'archetipo dei linguaggi orientati agli oggetti e perché?

È stato utile?

Soluzione

Definizioni per l'orientamento agli oggetti sono ovviamente a enorme barattolo di vermi, ma ecco i miei 2 centesimi:

Per me, l'orientamento agli oggetti riguarda gli oggetti che collaborano inviando messaggi.Questo è, per me, il tratto più importante di un linguaggio orientato agli oggetti.

Se dovessi stilare un elenco ordinato di tutte le caratteristiche che un linguaggio orientato agli oggetti dovrebbe avere, sarebbe questo:

  1. Oggetti che inviano messaggi ad altri oggetti
  2. Tutto è un oggetto
  3. Rilegatura tardiva
  4. Polimorfismo del sottotipo
  5. Eredità o qualcosa di similmente espressivo, come Delegazione
  6. Incapsulamento
  7. Nascondere le informazioni
  8. Astrazione

Ovviamente, questo elenco è molto controverso, poiché esclude una grande varietà di linguaggi ampiamente considerati orientati agli oggetti, come Giava, C# E C++, che violano tutti i punti 1, 2 e 3.Tuttavia, non c'è dubbio che questi linguaggi consentano la programmazione orientata agli oggetti (ma è così C) e persino facilitarlo (cosa che C non fa).Quindi, sono arrivato a chiamare i linguaggi che soddisfano questi requisiti "puramente orientati agli oggetti".

Come linguaggi archetipici orientati agli oggetti chiamerei Se stesso E Neolingua.

Entrambi soddisfano i requisiti sopra menzionati.Entrambi sono ispirati e successori Chiacchiere, ed entrambi riescono effettivamente ad essere "più OO" in un certo senso.Ciò che mi piace del Sé e della Neolingua è che entrambi portano all'estremo il paradigma dell'invio di messaggi (la Neolingua ancor più del Sé).

In neolingua, qualunque cosa è un messaggio inviato.Non ci sono variabili di istanza, campi, attributi, costanti, nomi di classi.Sono tutti emulati utilizzando getter e setter.

Nel Sé, ci sono niente classi, solo oggetti.Ciò enfatizza ciò che è OO Veramente Di:oggetti, non classi.

Altri suggerimenti

Secondo Booch, i seguenti elementi:Maggiore:

  • Astrazione
  • Incapsulamento
  • Modularità
  • Gerarchia (ereditarietà)

Minore:

  • Digitando
  • Concorrenza
  • Persistenza

Fondamentalmente l'orientamento agli oggetti si riduce davvero al "passaggio di messaggi"

In un linguaggio procedurale, chiamo una funzione come questa:

  f(x)

E il nome f è probabilmente legato a un particolare blocco di codice in fase di compilazione.(A meno che questo non sia un linguaggio procedurale con funzioni di ordine superiore o puntatori a funzioni, ma ignoriamo questa possibilità per un secondo.) Quindi questa riga di codice può significare solo una cosa inequivocabile.

In un linguaggio orientato agli oggetti passo un messaggio a un oggetto, forse in questo modo:

 o.m(x) 

In questo caso.m non è il nome di un blocco di codice, ma un "selettore di metodo" e quale blocco di codice viene chiamato dipende in qualche modo dall'oggetto o.Questa riga di codice è più ambigua o generale perché può significare cose diverse in situazioni diverse, a seconda di o.

Nella maggior parte dei linguaggi OO, l'oggetto o ha una "classe" e la classe determina quale blocco di codice viene chiamato.In un paio di linguaggi OO (il più famoso, Javascript) o non ha una classe, ma ha metodi direttamente collegati ad essa in fase di esecuzione o li ha ereditati da un prototipo.

La mia demarcazione è che né le classi né l'ereditarietà sono necessarie affinché una lingua sia OO.Ma questa gestione polimorfica dei messaggi è essenziale.

Sebbene tu possa fingere questo con puntatori a funzione, ad esempio C, ciò non è sufficiente affinché C sia chiamato un linguaggio OO, perché dovrai implementare la tua infrastruttura.Puoi farlo, e uno stile OO è possibile, ma la lingua non te lo ha dato.

Non sono proprio i linguaggi ad essere OO, è il codice.

È possibile scrivere codice C orientato agli oggetti (con strutture e anche membri puntatori a funzione, se lo si desidera) e ne ho visti alcuni ottimi esempi.(Mi viene in mente l'SDK di Quake 2/3.) È anche sicuramente possibile scrivere procedure (cioècodice non OO) in C++.

Detto questo, direi che è il supporto della lingua per la scrittura di un buon codice OO che lo rende un "linguaggio orientato agli oggetti". Non mi preoccuperei mai di usare i membri del puntatore della funzione in Structs in C, ad esempio, per quelle che sarebbero le normali funzioni dei membri;quindi dirò che il C non è un linguaggio OO.

(Espandendo questo argomento, si potrebbe dire che Python non è nemmeno orientato agli oggetti, con il riferimento obbligatorio a "self" in ogni passaggio e costruttori chiamati dentro, cosa no;ma questa è una discussione religiosa.)

Smalltalk è solitamente considerato l'archetipo del linguaggio OO, sebbene Simula sia spesso citato come il primo linguaggio OO.

Le attuali lingue OO possono essere vagamente classificate in base alla lingua da cui prendono in prestito la maggior parte dei concetti:

  • Simili a chiacchiere:Ruby, Obiettivo-C
  • Simil-simulativa:C++, Object Pascal, Java, C#

Per quanto ne so, la visione principale di ciò che rende un linguaggio "orientato agli oggetti" è supportare l'idea di raggruppare dati e metodi che funzionano su tali dati, cosa che generalmente si ottiene attraverso classi, moduli, ereditarietà, polimorfismo, ecc.

Vedere questa discussione per una panoramica di ciò che le persone pensano (pensano?) significhi orientamento agli oggetti.

Per quanto riguarda il linguaggio OO "archetipico", questo è davvero Smalltalk, come ha sottolineato Kristopher.

Supporta classi, metodi, attributi, incapsulamento, occultamento dei dati, ereditarietà, polimorfismo, astrazione...?

Trascurando le implicazioni teoriche, sembra di sì

"Qualsiasi lingua che ha una parola chiave chiamata 'classe'" :-P

Per approfondire ciò che ha detto aib, direi che un linguaggio non è realmente orientato agli oggetti a meno che le librerie standard disponibili non siano orientate agli oggetti.Il più grande esempio di questo è PHP.Sebbene supporti tutti i concetti standard orientati agli oggetti, il fatto che una percentuale così grande delle librerie standard non siano orientate agli oggetti significa che è quasi impossibile scrivere il codice in modo orientato agli oggetti.

Non importa che stiano introducendo gli spazi dei nomi se tutte le librerie standard richiedono ancora di prefissare tutte le chiamate di funzione con cose come mysql_ e pgsql_, quando in un linguaggio che supportava gli spazi dei nomi nell'API reale, potresti sbarazzarti delle funzioni con mysql_ e inserisci semplicemente un semplice "include system.db.mysql.*" nella parte superiore del file in modo che possa sapere da dove provengono quelle cose.

quando puoi creare classi, è orientato agli oggetti
Per esempio :Java è orientato agli oggetti, Javascript no e C++ sembra una sorta di linguaggio "curioso per gli oggetti"

Nella mia esperienza, i linguaggi non sono orientati agli oggetti, il codice lo è.

Qualche anno fa stavo scrivendo una suite di programmi in AppleScript, che in realtà non impone alcuna funzionalità orientata agli oggetti, quando ho iniziato a grok OO.È goffo scrivere oggetti in AppleScript, sebbene sia possibile creare classi, costruttori e così via se ci si prende il tempo per capire come.

La lingua era quella corretta per il dominio:far sì che diversi programmi sul Macintosh lavorino insieme per eseguire alcune attività automatiche basate su file di input.Prendersi la briga di applicare autonomamente uno stile orientato agli oggetti è stata la scelta di programmazione corretta perché ha prodotto un codice più facile da risolvere, testare e comprendere.

La caratteristica che ho notato di più nel cambiare il codice da procedurale a OO è stata l'incapsulamento:sia delle proprietà che delle chiamate ai metodi.

Semplici: (confronta il carattere dell'assicurazione)

1-polimorfismo 2-eredità a 3 incapsulazioni 4-re.:)

Oggetto:Un oggetto è un archivio di dati.Ad esempio, se MyList è un oggetto ShoppingList, MyList potrebbe registrare la tua lista della spesa.

Classe:Una classe è un tipo di oggetto.Potrebbero esistere molti oggetti della stessa classe;ad esempio, MyList e YourList possono essere entrambi oggetti ShoppingList.

Metodo:Una procedura o funzione che opera su un oggetto o una classe.Un metodo è associato a una particolare classe.Ad esempio, addItem potrebbe essere un metodo che aggiunge un articolo a qualsiasi oggetto ShoppingList.A volte un metodo è associato a una famiglia di classi.Ad esempio, addItem potrebbe operare su qualsiasi elenco, di cui ShoppingList è solo un tipo.

Eredità:Una classe può ereditare proprietà da una classe più generale.Ad esempio, la classe ShoppingList eredita dalla classe List la proprietà di memorizzare una sequenza di articoli.

Polimorfismo:La possibilità di far funzionare una chiamata al metodo su diverse classi di oggetti, anche se tali classi necessitano di implementazioni diverse della chiamata al metodo.Ad esempio, una riga di codice potrebbe essere in grado di chiamare il metodo "addItem" su ogni tipo di elenco, anche se aggiungere un articolo a una lista degli acquisti è completamente diverso dall'aggiungere un articolo a un carrello degli acquisti.

Orientato agli oggetti:Ogni oggetto conosce la propria classe e quali metodi manipolano gli oggetti in quella classe.Ogni ShoppingList e ogni ShoppingCart sanno quale implementazione di addItem si applica ad esso.

In questo elenco, l'unica cosa che distingue veramente i linguaggi orientati agli oggetti dai linguaggi procedurali (C, Fortran, Basic, Pascal) è il polimorfismo.

Fonte: https://www.youtube.com/watch?v=mFPmKGIrQs4&list=PL-XXv-cvA_iAlnI-BQr9hjqADPBtujFJd

Sono felice di condividerlo con voi ragazzi, è stato piuttosto interessante e utile per me.Questo è un estratto da un'intervista di Rolling Stone del 1994 in cui Steve (non un programmatore) spiega l'OOP in termini semplici.

Jeff Goodell:Spiegheresti, in termini semplici, esattamente cos'è il software orientato agli oggetti?

Steve Jobs:Gli oggetti sono come le persone.Vivono, respirano cose che hanno dentro di sé la conoscenza su come fare le cose e hanno una memoria dentro di sé in modo che possano ricordare le cose.E invece di interagire con loro a un livello molto basso, interagisci con loro a un livello di astrazione molto elevato, come stiamo facendo proprio qui.

Ecco un esempio:Se sono il tuo oggetto di lavanderia, puoi darmi i tuoi vestiti sporchi e inviarmi un messaggio che dice: "Puoi farmi lavare i vestiti, per favore." Mi capita di sapere dove si trova il miglior posto di lavanderia a San Francisco.E parlo inglese e ho dollari in tasca.Quindi esco, fermo un taxi e dico all'autista di portarmi in questo posto a San Francisco.Vado a farti lavare i vestiti, salto nel taxi e torno qui.Ti do i tuoi vestiti puliti e dico: “Ecco i tuoi vestiti puliti”.

Non hai idea di come ho fatto.Non sei a conoscenza della lavanderia.Forse parli francese e non sai nemmeno fermare un taxi.Non puoi pagarne uno, non hai dollari in tasca.Eppure sapevo come fare tutto questo.E non dovevi sapere nulla di tutto ciò.Tutta quella complessità era nascosta dentro di me e siamo riusciti a interagire a un livello di astrazione molto elevato.Ecco cosa sono gli oggetti.Incapsulano la complessità e le interfacce con tale complessità sono di alto livello.

Archetipo

La capacità di esprimere scenari del mondo reale nel codice.

foreach(House house in location.Houses)
{
 foreach(Deliverable mail in new Mailbag(new Deliverable[]
              {
              GetLetters(), 
              GetPackages(), 
              GetAdvertisingJunk()
              })
 {
    if(mail.AddressedTo(house))
    {
        house.Deliver(mail);
    }
 }
}

-

foreach(Deliverable myMail in GetMail())
{
    IReadable readable = myMail as IReadable;
    if ( readable != null )
    {
        Console.WriteLine(readable.Text);
    }
}

Perché?

Per aiutarci a capirlo più facilmente.Ha più senso nella nostra testa e, se implementato correttamente, rende il codice più efficiente, riutilizzabile e riduce la ripetizione.

Per raggiungere questo obiettivo è necessario:

  • Puntatori/Riferimenti per garantire che questo == questo e questo!= quello.
  • Classi indicare (es.Arm) che memorizzano dati (int hairyness) e operazioni (Throw(IThrowable))
  • Polimorfismo (ereditarietà e/o interfacce) per trattare oggetti specifici in modo generico in modo da poter leggere libri e graffiti sul muro (entrambi implementano IReadable)
  • Incapsulamento perché una mela non espone una proprietà Atoms[]
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top