In Objective C ogni oggetto deriva in maniera diretta o indiretta da una classe base, tipicamente un oggetto root. Questi oggetti sono detti "root" perché non derivano da nessun altro oggetto. L'oggetto root per eccellenza è NSObject
da cui derivano quasi tutte le classe di ObjectiveC, quelle che non derivano da esso tuttavia implementano un protocollo (una sorta di interfaccia java) che li riconduce come comportamento a NSObject
.
In ogni caso nella pratica possiamo dire che qualsiasi oggetto deriva da NSObject. Nel corso della guida esamineremo alcuni dei metodi ereditati da questa classe, che risultano utili per le impostazioni fondamentali di ogni oggetto.
La definizione di una classe in Objective C prevede due parti:
- l'interfaccia - o header. È pubblica (per permettere ad altri di utilizzare la classe) e viene codificata in un file che ha estensione
.h
ed include tutte le dichiarazioni delle variabili di istanza della classe, delle proprietà e delle firme dei metodi - l'implementazione della classe. È privata e contiene il codice di ogni metodo e il completamento delle proprietà dichiarate nell'interfaccia e viene definita in un file con estensione
.m
Le variabili di istanza
Ogni oggetto ha un suo stato interno, rappresentato dalle variabili di istanza. Queste variabili sono considerate private per default non possono essere modificate né lette da oggetti esterni.
Le variabili di istanza possono essere dei tipi scalari del linguaggio C (int
, float
, decimal
ect.) oppure altri oggetti Objective C. Ad esempio la classe NSString
rappresenta una stringa. La sintassi per la dichiarazione è uguale a quella usata in C:
tipo nomeVariabile;
Inoltre, come in C, per definire una variabile puntatore facciamo precedere il nome un asterisco (*
). Questo risulta molto utile, poiché in Objective C tutti gli oggetti sono riferiti tramite puntatori.
Per esporre queste variabili utilizziamo metodi creati a questo scopo: i classici setter, se modificano il valore della variabile, e getter se ne restituiscono il valore. Le variaibili esposte attraverso getter e setter sono le proprietà dell'oggetto e la loro implementazione interna alla classe viene nascosta da questo meccanismo di incapsulamento.
Metodi di istanza e metodi di classe (statici)
La dichiarazione dei metodi di istanza è sempre preceduta dal segno meno (-
) seguita dal tipo di ritorno, tra parentesi tonde, e dal nome del metodo; anche qui, per convenzione, si segue la sintassi CamelCase
eccetto per l'iniziale della parola che è sempre in minuscolo.
Qualora il metodo accetti uno o più parametri il nome è seguito da un segno di due punti, dal tipo del parametro inserito tra parentesi tonde e dal nome del parametro.
Se il metodo accetta più di un parametro, tra un parametro ed un altro è possibile inserire una parola arbitraria che spiega il significato del parametro successivo; la parola arbitraria è sempre seguita dal segno di due punti.
La sintassi di Obj-C nelle dichiarazioni è tra caratteristiche ereditte da SmallTalk e può richiedere un po' di tempo per essere assimilata, specie per chi proviene da altri linguaggi come Java o C#, ma una volta presa la mano si possono scrivere dei metodi che risultino molto leggibili. Ad esempio la seguente definizione di metodo:
- (double) calcolaVelocitaNello:(double)spazio percorsoNelTempo:(int)secondi;
può risultare più intuitivo come scopo e parametri di una funzione C così definita:
double calcolaVelocità(double spazio, int secondi);
anche se quest'ultima definizione risulta più compatta.
Oltre ai metodi di istanza, che abbiamo appena visto, possiamo dichiarare anche "metodi di classe", quelli che in Java chiameremmo "metodi statici", sono quei metodi che vanno invocati direttamente dalla classe e non da una particolare istanza di essa.
I metodi statici sono dichiarati in modo analogo a quelli di istanza, cambia solamente il segno che precede la definizione: un segno 'più' (+
) al posto del meno e la modalità di invocazione, come vedremo tra poco.