Permettimi di rispondere alle tue domande con altre domande:
Cos'è che posso fare con un linguaggio strutturato che non posso fare con un linguaggio a spaghetti e privo di funzioni?Cos'è che posso fare con le classi che non posso fare con una funzione normale?
Perché ragionare in "class" e non più in "function"?
Perchè dichiarare una variabile all'interno di una funzione?... mi chiedo: perchè nasconderla? Che senso ha?Perché ad esempio dichiarare una variabile "privata" o "protetta"?... mi chiedo: perché proteggerla? Che senso ha?
Sono io che programmo, sono io che scrivo il programma in modo tale che non venga utilizzata quella variabile in altri ambiti... non ho bisogno di proteggerla o nasconderla...
************************************
Adesso diamo delle risposte generiche che siano di stimolo.
Domanda uno: Perchè ragionare per classi e piuttosto che funzioni.
Premesso che entrambi gli approcci conducono alla soluzione del problema, è appunto il modo di approcciarsi al problema che cambia.
Con la programmazione procedurale tu ipotizzi un flusso del programma, quindi inizi a buttare giù delle funzioni e quindi delle strutture dati su cui tali funzioni operano. Cambiare la struttura dati può voler dire andare a caccia di tutte le funzioni che ne fanno uso oltre al dover verificare che quanlche funzione non produca effetti indesiderati rispetto ad altre funzioni.
Con le classi parti dagli oggetti del tuo programma (o almeno ci provi) andandoli a descrivere tramite caratteristiche e azioni cui l'oggetto è in grado di rispondere. Le caratteristiche sono i dati e le azioni sono le funzioni che operano su tali dati. Questa descrizione di caratteristiche e azioni costituirà la classe che utilizzi come un timbro per dare origine agli oggetti. L'oggetto è quindi una scatola nera di cui puoi anche ignorare il funzionamento interno (dati, funzioni e come le funzioni operino con i dati) ma con cui puoi interagire tramite una interfaccia definita dai dichiaratori di accesso public, private e protected. Col tempo potresti andare a modificare la classe (dati e funzioni) per rispondere a nuove esigenze. Le parti di programma che utilizzano quell'oggetto non saranno turbati se non turberai l'interfaccia cui il programma accede.
Questa è una tanto per dire, la prima che mi è venuta in mente...
Domanda due: Perchè dichiarare una variabile protected o private?
Come abbiamo detto prima la classe fornisce una interfaccia. Diciamo un punto di aderenze o contatto tra il programma, e l'uso che questo fa degli oggetti prodotti dalla classe. Ovviamente una interfaccia deve esporre solo ciò che serve, anche al fine di evitare accidentali modifiche a parte dell'oggetto, ai suoi dati, che potrebbero innescare risultati inattesi. In generale non c'è motivo per cui una classe debba esporre in modo diretto i propri dati, quindi le variabili dovrebbero essere sempre private. Anche i discendenti di una classe che in genere specializzano la classe stessa non dovrebbero accedere alle variabili del genitore ma agire sulla classe tramite i metodi (azioni... funzioni) questo sempre per garantire coerenza nel contenuto dati dell'oggetto. Al più ai discendenti si possono garantire dei privilegi ulteriori tramite dei metodi protected, che in generale al programma non interessano, ma che per un discedente possono essere fondamentali per conoscere o modificare il proprio stato, senza manomettere o correre il rischio di rendere incoerente la scatola nera prodotta dalla classe genitore o superclasse.
Un caso in cui dichiarare una variabile come protected potrebbe essere quando il mio oggetto delega alcune funzionalità ad altro oggetto memorizzato fra le proprie variabili. in tal caso poteri rendere la variabile (che contiene un oggetto) protected in modo che i miei discendenti vi accedano e lo utilizzino tremite i propri metodi. Ma anche in questo caso utilizzerei il private per la variabile. Renderei accessibile tramite metodo il contenuto della variabile in questione ed il suo settaggio, in modo da poter sempre verificare che non venga fatto un uso impoprio della variabile e non ci sia il rischio di oscillazioni nel programma.