In molti altri linguaggi come C ++ e Javascript, OOP è facoltativo. Il codice procedurale è ok. Ma in linguaggi come Java e C #, OOP è in qualche modo applicato. Tutto deve essere parte di una classe o di un oggetto. Quali sono i vantaggi?
Sia C # che Java sono contrassegnati come lingue conosciute non per ciò che abilitano, ma per ciò che disabilitano , in termini di set di funzionalità che usano. (C # meno così oggigiorno con LINQ ma questa è una lattina completamente diversa di worm) Entrambi questi linguaggi sono progettati in modo tale che è più difficile creare disegni sbagliati, a scapito di una certa libertà per il programmatore. In generale, la progettazione orientata agli oggetti produce progetti più riutilizzabili e manutenibili rispetto alla progettazione non orientata agli oggetti. (Nota: io dico "generalmente" qui - alcuni disegni sono ovviamente più facilmente espressi usando (per esempio) le primitive di programmazione funzionale) Pertanto, OO è il paradigma predefinito supportato in queste lingue.
(Anche in questo caso C # è un po 'strano perché supporta lo stile di programmazione funzionale)
Non è tanto il fatto che l'OOP sia applicato, quanto il fatto che venga applicato un framework OOP. È possibile scrivere programmi procedurali in Java, anche se è più facile se sono solo un file.
Il vantaggio è l'uniformità. Ci sono diversi tipi di funzioni e dati in C ++, e questo a volte causa alcuni problemi e confusione, e per lo meno è molto altro da imparare. Con Java, hai funzioni membro (di classe o basate su oggetti) e dati simili, e il gioco è fatto.
Questo ha lo scopo di rendere Java più facile da leggere e scrivere, specializzandone un po 'la lingua.
Potrebbe essere "pensavano che fosse una buona idea in quel momento", cioè senza funzioni gratuite. 10-15 anni fa il mondo dello sviluppo era entusiasta di "Object Oriented" (proprio come sembrano essere eccitati da "Agile" in questo momento).
Anche così, non sono sicuro che ogni classe dovrebbe derivare da Object, ma senza generici dove devi lanciare tutto il tempo, aiuta e potrebbe essere la praticità che la VM che hanno costruito in quel momento era in grado di gestirlo meglio
L'MFC di Microsoft aveva anche un concetto di CObject in cima a una grande gerarchia.
Nella mia esperienza, la maggior parte degli orribili esempi di codice scadente Ho visto è scritto in Java o C #. Ho visto alcune cose cattive in linguaggi meno rigorosi, ma è niente rispetto agli orrori assoluti di fissare l'abisso di 1.000.000 di righe di codice C # con palla-di-fango statica copiata.
Non so perché sia così, ma la mia ipotesi è perché è più facile, anche possibile, continuare ad aggiungere sempre più codice (e più ...) in Java / C #, con la certezza che il compilatore ti dirà quando la tua sintassi è sbagliata. Sfortunatamente non ti dice quando il tuo design è sbagliato.
Non sto dicendo che Java / C # sia cattivo o altro, piuttosto il contrario. È solo che tutto questo, aiutando e rafforzando la sicurezza del tipo, rende possibile fare confusione molto più che in linguaggi più flessibili e non-enforcing.
Quindi non posso davvero dire che questa politica di "enforcement" abbia migliorato la qualità del codice in generale. Tuttavia, ha migliorato la quantità di codice, questo è certo.
C # 2.0 ha aggiunto il supporto per le classi static
quando è uscito 6-7 anni fa. Ciò trasforma una classe in un "modulo" (o "spazio dei nomi" a seconda della scelta del gergo) che contiene nient'altro che metodi e campi statici, consentendo in pratica di applicare la definizione e il consumo del tipo di stile non OOP.
Spesso l'OOP è incoraggiato, ma certamente non viene applicato. Sareste sorpresi di quanto le librerie .NET siano implementate come classi statiche.
Molte persone pensano che OOP sia il modo migliore per scrivere codice. Hanno ragione, sono sbagliati o sono aperti a opinioni / dibattiti ... non importa. Coloro che hanno scritto Java / C # credono ovviamente il primo.
È più facile imporre l'OOP come standard di codifica se il linguaggio stesso lo impone. Questo è anche il motivo per cui linguaggi come Java ti costringono a fare anche altre cose, come una classe pubblica per file.
Hanno in qualche modo un punto lì. È difficile convincere le persone a fare le cose nel modo desiderato. Offri loro troppa libertà e lo fanno a modo loro e speri che riesca attraverso la revisione. Se gli strumenti stessi li costringono a un certo modo di fare le cose, allora non devi discutere e / o ottenere il consenso della squadra (che comunque tutti ignorano prontamente).
D'altra parte, non sono mai stato d'accordo con qualcosa che sia stato applicato da Java. Per uno, ci sono delle eccezioni a ogni regola e Java semplicemente non lo prevede.
Non è obbligatorio, dopotutto, come si suol dire: un vero sviluppatore può scrivere codice FORTRAN in qualsiasi lingua.
Ma devo ammettere che non capisco il senso della domanda. Beh perchè no? Ci sono così tante lingue là fuori, quindi Gosling ei suoi amici hanno deciso di crearne uno basato solo su classi e oggetti (ok, e alcuni tipi primitivi). L'idea non era del tutto innovativa, ma volevano anche la leggibilità, la sintassi simile a C e le solide basi astratte.
Ogni lagnuaggio rappresenta un compromesso tra la libertà e l'applicazione rigorosa di un insieme di principi che aiutano a evitare errori. Assemblaggio ti dà la totale libertà e anche ogni possibilità di spararti ai piedi. Ada è stata progettata per offrirti pochissima libertà ma anche meno opportunità di autodistruzione. Uno non è intrinsecamente migliore dell'altro.
Java è solo un linguaggio che si spinge verso la parte più ristretta dello spettro, più severo del C ++, ma non immergersi nelle vere profondità della tipizzazione strong.
C # è in qualche modo più semplice da spiegare, è stata la risposta di Microsoft alla popolarità di Java (e ai loro tentativi falliti di intrufolare le classi proprietarie nella loro implementazione del framework dell'applet:)).
Per soddisfare i requisiti di conformità alle parole chiave.
(Questo è solo in parte inteso come uno scherzo, ma è vero).
Queste lingue sono rivolte alle aziende e chi prende le decisioni in media in BigCorporation non ha alcuna conoscenza delle tecniche di programmazione, ma legge ovunque che OOP è il futuro.
Almeno, questo era vero 5-15 anni fa.
Al giorno d'oggi, molti più prodotti vengono prodotti dalle startup piuttosto che dalle grandi aziende, quindi Java e C # finiscono per perdere (in un certo senso). Poiché miravano a soddisfare il clueless middle manager, i tipi più tecnici e di hacker continuavano a utilizzare tecnologie diverse (php, ruby, python e più recentemente: node.js).
C ++ è stato costruito (in origine) sopra C, che è procedurale. I programmi C ++ hanno ancora una funzione "principale" come punto di ingresso di un programma, che è un'eredità procedurale.
JavaScript è orientato agli oggetti, ma si basa sul modello prototipo e delegazione piuttosto che sul modello di ereditarietà di classe (questi modelli sono funzionalmente equivalenti e ugualmente validi). Il framework OO in JavaScript è implicito. Solo perché puoi scrivere
<script> var i=21*15; </script>
non significa che stai effettivamente usando un codice procedurale; sotto il cofano hai implicitamente creato un metodo anonimo che appartiene all'oggetto Document [avvertenza: sto indovinando sulla base del debug del DOM; Esperti di JavaScript per favore, correggere]
Java e C # sono stati progettati per essere orientati agli oggetti usando il modello di classe ed ereditarietà, quindi ogni programma deve avere una classe (statica) e un punto di ingresso principale. Oltre a questo, però, sei libero di essere procedurale come preferisci.
La tua domanda non è perché queste lingue supportano OOP tanto quanto perché non consentono l'OOP. In particolare, suppongo che ciò significhi perché non consentono funzioni nude che non fanno parte di alcuna classe.
Sembra che la risposta più semplice sia che il supporto che renderebbe quei linguaggi più complessi (considera che cose come spazi dei nomi e risoluzione di sovraccarico dovrebbero essere in grado di gestire funzioni nude e quelle funzioni sono già complesse in cambio di piccoli benefici: si può sempre fare semplicemente una programmazione procedurale usando le funzioni statiche. Quale reale vantaggio ti darebbero le funzioni non di classe?
Non si tratta di "forzare" le cose. È solo che le alcune soluzioni possono essere espresse puramente in concetti OO, quindi il linguaggio fornisce solo concetti OO.
Questa è una supposizione sfrenata, ma un motivo potrebbe essere che rende l'IDE magico come IntelliSense più facile / più utile. In C ++ ogni funzione della libreria standard C si trova nello spazio dei nomi globale. Ogni classe e funzione della libreria standard C ++ si trova nello spazio dei nomi std
. E molti programmi C ++ su cui ho lavorato mettono anche tutto nello spazio dei nomi globale (o usano using namespace XYZ
all'inizio di ogni file). Quindi se premi Ctrl-Spazio da qualche parte in un file, ottieni una lunga lista molto di ogni funzione globale. In C #, tutte le funzioni statiche come Math.Sin
o Buffer.BlockCopy
sono contenute in uno spazio dei nomi. Quindi tutto ciò che ottieni premendo Ctrl-Spazio sono alcune classi come Math
, Buffer
, ...
Una lingua è solo un'astrazione sopra il codice assembly. La scelta dell'astrazione è semplicemente lì per aiutarti a risolvere un problema (rendendo più facili le attività mirate e alcuni problemi più difficili da sbagliare).
Dovevano scegliere un'astrazione. E come la vedo io (ignorando tutte le ragioni di business) C # era l'astrazione concettuale su C ++ che era l'astrazione su C tranne che con le classi (OO). C # ha semplicemente cercato di rafforzare il modello OO e risolvere problemi come la perdita di memoria e l'astrazione di alcune delle complessità di basso livello.
Se non è adatto al tuo dominio problematico, scegli semplicemente la lingua appropriata con la migliore astrazione per il tuo dominio problematico.
Come affermato da altri. Non lo è!
Se vuoi sapere perché è (o è quasi), allora guarda Eiffel. Vale la pena dare un'occhiata a; puoi imparare Eiffel più velocemente di C # o Java.
Finalmente comprenderai OO, Design per contratto, Proprietà di ereditarietà, C # e molto altro ancora.
Un punto che non è stato menzionato è che in molti framework orientati agli oggetti basati su garbage collection, è assolutamente imperativo al 100% che il sistema conosca l'ubicazione di ogni singolo riferimento di oggetto - non solo ogni oggetto, ma ogni riferimento anche - in qualsiasi momento in cui può verificarsi la raccolta dei rifiuti; se c'è qualche thread Th
in cui il sistema non conosce l'ubicazione di ogni singolo riferimento di oggetto e la garbage collection diventa necessaria, tutti gli altri thread devono attendere il thread Th
per raggiungere un punto in cui il sistema sa dove tutto i suoi riferimenti agli oggetti sono.
Il requisito di cui sopra è molto più severo di qualsiasi cosa che esiste per C o C ++. In C o C ++, si può costruire un'unione che combina un tipo numerico intero con un puntatore, e se il codice tiene traccia di se la cosa contiene un intero o un puntatore, non importa se il framework runtime può dire quale tipo la cosa è. Un simile approccio non funzionerebbe in un linguaggio raccolto dalla spazzatura. Se interpretare il contenuto di un'unione come un puntatore farebbe riferimento a un oggetto che viene ricollocato, è assolutamente necessario aggiornare il contenuto dell'unione per contenere il nuovo indirizzo se l'ultima cosa memorizzata era un puntatore, ma è ugualmente imperativo che sia lasciato solo se dovrebbe contenere un numero intero. Non c'è semplicemente nulla che il runtime possa fare tranquillamente se non può richiedere che i riferimenti agli oggetti siano archiviati in posizioni di memorizzazione del tipo di riferimento agli oggetti e da nessun'altra parte.
Leggi altre domande sui tag object-oriented c# java