








Studia grazie alle numerose risorse presenti su Docsity
Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium
Prepara i tuoi esami
Studia grazie alle numerose risorse presenti su Docsity
Prepara i tuoi esami con i documenti condivisi da studenti come te su Docsity
Trova i documenti specifici per gli esami della tua università
Preparati con lezioni e prove svolte basate sui programmi universitari!
Rispondi a reali domande d’esame e scopri la tua preparazione
Riassumi i tuoi documenti, fagli domande, convertili in quiz e mappe concettuali
Studia con prove svolte, tesine e consigli utili
Togliti ogni dubbio leggendo le risposte alle domande fatte da altri studenti come te
Esplora i documenti più scaricati per gli argomenti di studio più popolari
Ottieni i punti per scaricare
Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium
Questi appunti spiegano: Come funziona Java (bytecode, compilazione, interpretazione, comandi: javac, java) Incapsulamento ed information hiding (dichiarazioni public, private) Attributi e metodi di classe (static). Overloading Ereditarietà, Polimorfismo, Overriding, classi astratte, Interfacce La gestione delle eccezioni Le diverse strutture dati e loro caratteristiche e utilizzi (ArrayList, , Mappe e loro derivazioni) Code e Pile dal punto di vista logico La complessità degli algoritmi
Tipologia: Appunti
1 / 14
Questa pagina non è visibile nell’anteprima
Non perderti parti importanti!









Verifica di Informatica -Teoria valida per orale (gli assenti verranno interrogati) Come funziona Java (bytecode, compilazione, interpretazione, comandi: javac, java) Incapsulamento ed information hiding (dichiarazioni public, private) Attributi e metodi di classe (static). Overloading Ereditarietà, Polimorfismo, Overriding, classi astratte, Interfacce La gestione delle eccezioni Le diverse strutture dati e loro caratteristiche e utilizzi (Liste, Mappe e loro derivazioni) Code e Pile dal punto di vista logico La complessità degli algoritmi per cominciare:
Un linguaggio a oggetti (o linguaggio orientato agli oggetti, OOP – Object Oriented Programming) è un linguaggio di programmazione che si basa sull’idea di rappresentare tutto tramite oggetti , cioè entità che combinano dati e comportamenti. È un modo di programmare che imita il mondo reale: invece di pensare in termini di funzioni isolate, pensi in termini di “cose” che hanno caratteristiche e azioni.
Un linguaggio a oggetti è un linguaggio in cui costruisci il programma usando classi e oggetti. ● Classe → il progetto ● Oggetto → l’istanza reale costruita da quel progetto ● Attributi → i dati dell’oggetto ● Metodi → le azioni che l’oggetto può fare Java è uno dei linguaggi più “puri” in questo senso: tutto ruota attorno alle classi e agli oggetti.
Per rendere il codice:
● più organizzato ● più facile da mantenere ● più riutilizzabile ● più vicino al modo in cui ragioniamo nella vita reale Se devi rappresentare una persona, un’auto, un prodotto, un conto bancario… un oggetto è perfetto.
I linguaggi OOP supportano quattro concetti fondamentali:
● Java ● C++ ● Python (ibrido, ma supporta OOP molto bene) ● C# ● JavaScript (basato su oggetti, ma con un modello a prototipi)
-Compilato: perché il sorgente viene trasformato in bytecode tramite javac. -Interpretato: perché la JVM può eseguire il bytecode istruzione per istruzione. -Ottimizzato: grazie al JIT, che porta Java vicino alle prestazioni dei linguaggi compilati nativamente (come C++). Java unisce i vantaggi dei linguaggi compilati (velocità) e interpretati (portabilità) grazie al bytecode. Il codice sorgente viene compilato in bytecode, un formato intermedio eseguibile dalla JVM (Java Virtual Machine) su qualsiasi sistema operativo.
● Avvio più lento: la fase di caricamento della JVM può rallentare l’esecuzione iniziale. ● Gestione memoria: il Garbage Collector automatizza la pulizia, ma può introdurre pause imprevedibili.
L’ incapsulamento e l’ information hiding sono due concetti centrali della programmazione orientata agli oggetti, e in Java si realizzano principalmente attraverso le dichiarazioni di visibilità (public, private, protected).
L’incapsulamento significa “racchiudere” i dati e i metodi che li gestiscono all’interno di una classe, impedendo l’accesso diretto dall’esterno. In pratica, una classe diventa una sorta di “scatola nera”: dall’esterno si possono usare solo le funzionalità che la classe decide di esporre, mentre i dettagli interni restano nascosti. ● Obiettivo: proteggere lo stato interno di un oggetto da modifiche non controllate. ● Realizzazione: dichiarare gli attributi come private e fornire metodi pubblici (public) per accedervi o modificarli (i cosiddetti getter e setter ). Esempio: Qui il campo saldo è incapsulato : non può essere modificato direttamente da chi usa la classe, ma solo tramite i metodi deposita() e getSaldo().
L’information hiding è strettamente collegato all’incapsulamento: significa nascondere i dettagli di implementazione e mostrare solo ciò che serve all’utente della classe. ● Con private nascondi campi e metodi che non devono essere visibili. ● Con public esponi solo l’interfaccia necessaria. ● In questo modo, chi usa la classe non deve sapere come funziona internamente, ma solo cosa può fare. Esempio:
Un utente del ContoBancario non sa come viene calcolato il saldo, né come è memorizzato. Gli basta sapere che può chiamare deposita() e getSaldo().
● public: accessibile da qualsiasi altra classe. ● private: accessibile solo all’interno della stessa classe. ● protected: accessibile nella stessa classe, nelle sottoclassi e nello stesso package. ● default (nessun modificatore) : accessibile solo all’interno dello stesso package.
● Sicurezza : impedisce modifiche non autorizzate ai dati. ● Manutenibilità : puoi cambiare l’implementazione interna senza modificare il codice che usa la classe. ● Chiarezza : separa l’interfaccia pubblica dai dettagli nascosti. In sintesi: incapsulamento significa racchiudere dati e metodi in una classe, mentre l’ information hiding significa nascondere i dettagli interni e mostrare solo ciò che serve. In Java questo si ottiene con i modificatori di accesso (public, private, protected), che permettono di controllare chi può vedere e usare cosa.
● Definizione : Un attributo dichiarato con la parola chiave static appartiene alla classe e non alle singole istanze. ● Memoria : Esiste una sola copia dell’attributo statico, condivisa da tutti gli oggetti della classe. Accesso : Può essere richiamato direttamente tramite il nome della classe, senza creare un oggetto. java class Contatore { static int totale = 0; } ● Qui Contatore.totale è accessibile senza istanziare Contatore. ● Uso tipico : ○ Costanti (static final) ○ Variabili condivise (es. contatori globali) ○ Configurazioni comuni a tutte le istanze
● Definizione : Un metodo dichiarato static appartiene alla classe e non richiede un oggetto per essere invocato. Accesso : Si richiama tramite NomeClasse.nomeMetodo().
● Definizione : consiste nel dichiarare più metodi con lo stesso nome ma con firme diverse (numero o tipo di parametri). ● Caratteristiche : ○ Avviene nella stessa classe. ○ Non dipende dal tipo di ritorno, ma solo dalla lista dei parametri. Esempio : ● Utilità : rende il codice più leggibile e naturale, permettendo di usare lo stesso nome per operazioni simili. mi
● Definizione : consiste nel riscrivere un metodo ereditato dalla superclass nella subclass, mantenendo la stessa firma. ● Caratteristiche : ○ Avviene tra superclass e subclass. ○ Richiede la stessa firma (nome, parametri, tipo di ritorno compatibile). ○ Può essere annotato con @Override per chiarezza. Esempio : ● Utilità : permette di adattare o specializzare il comportamento ereditato.
● Definizione : una classe dichiarata con abstract che può contenere sia metodi astratti (senza corpo) sia metodi concreti (con implementazione). ● Caratteristiche principali : ○ Può avere variabili di istanza e quindi mantenere uno stato. ○ Può avere costruttori. ○ Può contenere metodi abstract e metodi normali. ○ Non può essere istanziata direttamente. ○ Una sottoclasse deve implementare tutti i metodi astratti.
○ Una classe può implementare più interfacce contemporaneamente. Esempio: un’interfaccia Volante che dice “chi la implementa deve avere il metodo vola()”. Così sia un Uccello che un Aereo possono “volare”, anche se non hanno nulla in comune.
● Classi astratte : usale quando vuoi fornire una base comune con stato e comportamento parziale. ● Interfacce : usale quando vuoi definire un contratto che può essere condiviso tra classi non correlate. ● Dal Java 8 le interfacce sono diventate più potenti grazie ai metodi default e static, riducendo in parte la necessità delle classi astratte.
● Eccezione : un evento anomalo che interrompe il normale flusso del programma (es. divisione per zero, file non trovato). ● Gerarchia : tutte le eccezioni derivano dalla classe Throwable, che si divide in:
● Caratteristiche : ○ Collezione ordinata e indicizzata. ○ Permette duplicati. ○ Accesso agli elementi tramite indice. Caratteristica ArrayList LinkedList Struttura interna Array dinamico ridimensionabile Lista doppiamente concatenata Memoria Elementi in memoria contigua Nodi sparsi in memoria collegati da puntatori Overhead di memoria Solo dati (^) Dati + 2 puntatori (prev e next) per nodo Accesso casuale (get(i)) O(1) – accesso diretto tramite indice O(n) – deve scorrere i nodi Inserimento in mezzo O(n) – deve spostare gli elementi O(1) dopo aver trovato la posizione Rimozione in mezzo O(n) – sposta gli elementi successivi O(1) aggiornando i puntatori Inserimento alla fine (add) O(1) ammortizzato (finché non ridimensiona l’array) O(1)
Esempio logico : Immagina una fila al supermercato: il primo cliente che entra è il primo a essere servito.
● Complessità temporale : tempo di esecuzione in funzione della dimensione dell’input (n). ● Complessità spaziale : quantità di memoria utilizzata. ● Entrambe si esprimono con la notazione Big-O , che descrive il comportamento asintotico (cosa succede quando n diventa molto grande).
Deve controllare ogni elemento → tempo proporzionale a n.
Divide l’array a metà ogni volta → tempo logaritmico.
● Ottimizzazione : scegliere algoritmi più efficienti riduce drasticamente i tempi di esecuzione. ● Scalabilità : un algoritmo O(n log n) può gestire milioni di dati, uno O(n²) diventa impraticabile. ● Risorse : ridurre la memoria usata è cruciale in sistemi embedded o applicazioni mobili.
● Analizza sempre la dimensione dell’input : un algoritmo O(n²) può andare bene per piccoli dataset, ma non per grandi. ● Usa strutture dati appropriate (es. HashMap per accesso O(1) invece di List con accesso O(n)). ● Ricorda che la complessità teorica non considera costanti e dettagli pratici: a volte un algoritmo con complessità peggiore può essere più veloce su input piccoli.