{"id":660,"date":"2009-11-13T11:57:51","date_gmt":"2009-11-13T10:57:51","guid":{"rendered":"http:\/\/www.devapp.it\/wordpress\/?p=660"},"modified":"2009-12-14T16:13:09","modified_gmt":"2009-12-14T15:13:09","slug":"l007-%e2%80%93-objective-c-parte-ii","status":"publish","type":"post","link":"https:\/\/www.devapp.it\/wordpress\/l007-%e2%80%93-objective-c-parte-ii\/","title":{"rendered":"L#007 \u2013 Objective-C (Parte II) Definizione di una classe"},"content":{"rendered":"<p>Gran parte della programmazione object-oriented consiste nella scrittura di codice per nuovi oggetti, definendo quindi nuove classi. In Objective-C le classi vengono definite in due parti:<\/p>\n<ul>\n<li>Un&#8217;interfaccia dove vengono dichiarati i metodi, le variabili di istanza della classe e il nome della sua superclasse<\/li>\n<li>Un&#8217;implementazione che \u00e8 la reale definizione della classe (contiene il codice vero e proprio per implementare i suoi metodi)<\/li>\n<\/ul>\n<p><!--more--><\/p>\n<p><strong>File sorgenti<\/strong><br \/>\nAnche se il compilatore in realt\u00e0 non lo richiede, l&#8217;interfaccia e l&#8217;implementazione sono solitamente separati in due file differenti. Il file di interfaccia deve essere reso disponibile a chiunque utilizzi la classe.<\/p>\n<p>Un singolo file puo&#8217; dichiarare o implementare pi\u00f9 di una classe. Ciononostante, \u00e8 consuetudine avere file di interfaccia e di implementazione separati per ogni classe. Lasciare le interfacce delle classi separate riflette meglio la loro natura indipendente.<\/p>\n<p>Il nome di questi file solitamente coincide con il nome della classe. Il nome del file di implementazione ha estensione .m e indica che esso contiene il codice sorgente scritto in Objective-C. Al file di interfaccia puo&#8217; essere assegnata qualsiasi altra estensione. Dato che questi vengono inclusi in altri file, il loro nome solitamente ha estensione .h, tipida dei file di intestazione. Per esempio, la classe &#8220;Rectangle&#8221; della lezione precedente dovrebbe essere dichiarata in Rectangle.h e definita in Rectangle.m.<\/p>\n<p>Separare l&#8217;interfaccia di un oggetto dalla sua implementazione si adatta perfettamente alla progettazione di programmi object-oriented. Un oggetto pu\u00f2 essere visto dall&#8217;esterno come un&#8217;entit\u00e0 simile a una &#8220;scatola nera&#8221; che vive di vita propria.<\/p>\n<h4>Class Interface<\/h4>\n<p>La dichiarazione di un&#8217;interfaccia di una classe inizia con la direttiva per il compilatore &#8220;@interface&#8221; e termina con la direttiva &#8220;@end&#8221;. (Tutte le direttive per il compilatore in Objective-C iniziano con il carattere &#8220;@&#8221;)<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n@interface ClassName : ItsSuperclass\r\n{\r\n    instance variable declarations\r\n}\r\n\r\nmethod declarations\r\n\r\n@end\r\n<\/pre>\n<p>La prima linea della dichiarazione presenta il nome della nuova classe e un collegamento alla sua superclasse. La superclasse definisce la posizione della nuova classe nella struttura gerarchica legata all&#8217;ereditariet\u00e0 spiegata nella lezione precedente. Se i duepunti e il nome della superclasse sono omessi, la nuova classe \u00e8 dichiarata come una classe radice (root class), allo stesso livello della classe NSObject.<\/p>\n<p>Guardando la prima parte della dichiarazione, potete vedere come tra le parentesi graffe vengono racchiuse le dichiarazioni delle variabili di istanza, ovvero le strutture dei dati che sono parte di ogni istanza della classe. Di seguito un esempio di variabili di istanza che potrebbero essere dichiarate nella classe &#8220;Rectangle&#8221;:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\nfloat width;\r\nfloat height;\r\nBOOL filled;\r\nNSColor *fillColor;\r\n<\/pre>\n<p>I metodi per la classe sono dichiarati successivamente, dopo la chiusura della parentesi graffa che termina la dichiarazione delle variabili e prima della chiusura della dichiarazione della classe (prima di &#8220;@end&#8221;).<br \/>\nI nomi dei metodi che possono essere usati dagli oggetti di classe, metodi di classe, sono preceduti dal segno pi\u00f9 &#8220;+&#8221;:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n+ alloc;\r\n<\/pre>\n<p>I metodi che possono invece usare le istanze di una classe, metodi di istanza, sono preceduti dal segno meno &#8220;-&#8220;:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n- (void)display;\r\n<\/pre>\n<p>Anche se non \u00e8 una pratica comune, \u00e8 possibile definire un metodo di classe e un metodo di istanza con lo stesso nome. Un metodo puo&#8217; inoltre avere lo stesso nome di una variabile di istanza. Questo \u00e8 pi\u00f9 comune, specialmente se il metodo restituisce il valore nella variabile. Per esempio, Circle ha un metodo raggio che potrebbe corrispondere alla variabile di istanza raggio.<\/p>\n<p>I tipi di ritorno dei metodi sono dichiarati usanto la sintassi per il casting da un tipo ad un altro usata nello standard C:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n- (float)radius;\r\n<\/pre>\n<p>I tipi di dato per gli argomenti sono dichiarati allo stesso modo:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n- (void)setRadius:(float)aRadius;\r\n<\/pre>\n<p>Se il tipo restituisto dal metodo o il tipo degli argomenti non \u00e8 esplicitamente dichiarato, viene assunto il tipo di default ID. Come ad esempio il metodo alloc, illustrato poco fa.<\/p>\n<p>Quando c&#8217;\u00e8 pi\u00f9 di un argomento, questi sono dichiarati dentro il nome del metodo dopo i duepunti. L&#8217;argomento spezza il nome nella dichiarazione, come in un messaggio. Per esempio:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n- (void)setWidth:(float)width height:(float)height;\r\n<\/pre>\n<p>I metodi che accettano un numero variabile di argomenti vengono dichiarati utilizzando una virgola e i punti di puntini di sospensione:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n- makeGroup:group, ...;\r\n<\/pre>\n<h4>Importare l&#8217;interfaccia<\/h4>\n<p>Il file di interfaccia deve essere incluso in ogni modulo che dipende da essa, incluso ogni modulo che crea un&#8217;istanza della classe, invia messaggi per invocare un metodo dichiarato per la classe o fa riferimento a una variabile di istanza dichiarata al suo interno. Per inportare l&#8217;interfaccia si usa la direttiva &#8220;#import&#8221;;<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n#import \"Rectangle.h\"\r\n<\/pre>\n<p>Questa direttiva \u00e8 identica a &#8220;#include&#8221; tranne che per il fatto che assicura che lo stesso file non venga mai incluso pi\u00f9 di una volta.<\/p>\n<p>Dato che la classe eredita metodi e variabili da una superclasse, nella definizione dell&#8217;interfaccia occorre importare l&#8217;interfaccia della sua superclasse:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n#import \"ItsSuperclass.h\"\r\n\r\n@interface ClassName : ItsSuperclass\r\n{\r\n    instance variable declarations\r\n}\r\n\r\nmethod declarations\r\n\r\n@end\r\n<\/pre>\n<p>Quindi tutti i file di interfaccia includono, indirettamente, i file d&#8217;interfaccia delle loro superclassi. Quando un modulo di codice importa un&#8217;iternfaccia di una classe, esso eredita tutte le interfacce delle superclassi nella struttura gerarchica su cui si basa la classe stessa.<\/p>\n<h4>Riferimenti ad altre classi<\/h4>\n<p>Come abbiamo appena detto un file di interfaccia dichiara una classe e importando la sua superclasse, implicitamente contiene la dichiarazione di tutte le classi ereditate, da NSObject procedendo verso il basso fino alla sua superclasse. Se ci si riferisce ad una classe che non \u00e8 in questa gerarchia \u00e8 importante dichiaralra tramite la direttiva @class:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n@class Rectangle, Circle;\r\n<\/pre>\n<p>Questa direttiva informa semplicemente il compilatore che &#8220;Rectangle&#8221; e &#8220;Circle&#8221; sono nomi di classi. Non importa i file delle loro interfacce.<\/p>\n<h4>Implementazione<\/h4>\n<p>La definizione della classe \u00e8 strutturata in modo molto simile alla sua dichiarazione. Inizia con la direttiva &#8220;@implementation&#8221; e termina con la direttiva &#8220;@end&#8221;<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n@implementation ClassName : ItsSuperclass\r\n\r\n{\r\n    instance variable declarations\r\n}\r\n\r\nmethod definitions\r\n@end\r\n<\/pre>\n<p>Tuttavia, ogni file di implementazione deve importare la propria interfaccia. Per esempio, Rectangle.m importer\u00e0 Rectangle.h. Nell&#8217;implementazione non \u00e8 quindi necessario ripetere quanto contenuto nell&#8217;interfaccia, si pu\u00f2 tranquillamente omettere:<\/p>\n<ul>\n<li>Il nome della superclasse<\/li>\n<li>Le dichiarazioni delle variabili di istanza<\/li>\n<\/ul>\n<pre lang=\"objc\" escaped=\"true\">\r\n#import \"ClassName.h\"\r\n\r\n@implementation ClassName\r\n\r\nmethod definitions\r\n\r\n@end\r\n<\/pre>\n<p>I metodi per una classe sono definiti, come le funzioni in C, tra una coppia di parentesi graffe.<br \/>\nPrima delle parentesi sono invece dichiarate allo stesso modo di come sono state dichiarate nel file di interfaccia, ma senza il punto e virgola finale. Ad esempio:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n+ (id)alloc\r\n{\r\n    ...\r\n}\r\n\r\n- (BOOL)isFilled\r\n{\r\n    ...\r\n}\r\n\r\n- (void)setFilled:(BOOL)flag\r\n{\r\n    ...\r\n}\r\n<\/pre>\n<p>(Tradotto dalla documentazione ufficiale Apple)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Gran parte della programmazione object-oriented consiste nella scrittura di codice per nuovi oggetti, definendo quindi nuove classi&#8230;.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[9],"tags":[37,5,35,4,17],"class_list":["post-660","post","type-post","status-publish","format-standard","hentry","category-guide-teoriche","tag-classi","tag-objective-c","tag-oggetti","tag-programmazione","tag-teoria"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/660","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/comments?post=660"}],"version-history":[{"count":29,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/660\/revisions"}],"predecessor-version":[{"id":1312,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/660\/revisions\/1312"}],"wp:attachment":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media?parent=660"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/categories?post=660"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/tags?post=660"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}