La Implementació

La definició d'una classe és estructurades molt semblant a la seva declaració. Comença amb la directiva @implementation i finalitza amb la directiva @end:

@implementation NomDeClasse : LaSevaSuperclasse
{
    declaracions de variables d'instància
}
definicions de mètodes
@end

 

Tanmateix, cada fitxer d'implementació ha d'importar la seva pròpia interfície. Per exemple, Rectangle.m importa Rectangle.h. Com qué la implementació no necessita repetir cap de les declaracions que importa, pot ometre-les:

  • El nom de la superclasse.
  • Les declaracions de variables d'intància.

 

Això simplifica la implementació i la fà principalment lleials a les definicions de mètodes:

#import "NomDeClasse.h"

@implementation NomDeClasse 
definicions de mètodes
@end

 

Els mètodes per una classe estan definits, com les funcions C, dins un parell de claus. Abans de les claus, es declara igual qu en el fitxer de la interfície, però sense el doble punt. Per exemple:

{
    ...
}

- (BOOL)esPle
{
    ...
}

- (void)posaPle:(BOOL)flag
{
    ...
}

 

Els mètodes que tenen un nombre variable d'arguments els agafen com ho faria una funció:

#import 

 ...

- getGrup:grup, ...
{
    va_list ap;
    va_start(ap, grup);
    ...
}

 

Referenciant a Variables d'Instància

Per defecte, la definició d'un mètode d'instància té totes les variables d'instància de l'objecte dins el seu abast. Pot referir-se-s'hi simplement pel nom. Tanmateix el compilador crea les estructure de C equivalents per guardar les variables d'instància, la naturalessa exacta de la estructura es manté amagada. No necessties cap dels operadors d'estructura (. o ->) per referinr-nos a les dades de l'objecte. Per exemple, la definició del següent mètode es refereix a la variable d'instància ple del receptor:

- (void)posaPle:(BOOL)flag
{
    ple = flag;
    ...
}

 

Ni l'objecte que rep ni la seva variable d'instància ple s'ha declarat com un argument al seu mètode, aixó la variable d'instància romà dins el seu abast. Aquesta simplificació de la sintàxi del mètode és una abreviació significativa a l'escriure el codi en Objective-C.

Quan la variable d'instància arriba a un objecte que no és el receptor, el tipus de l'objecte ha de fer-se explícit al compilador a través de la definició estàtica. A la referència a la variable d'instància d'un objecte definit estàticament, l'operador del punter de l'estructura (-&;gt) s'utilitza.

Suposa, per exemple, que la classe Germà declara un objecte definit estàticament, bessó, com a variable d'intància:

@interface Germà : NSObject
{
    Germà *bessó;
    int gènere;
    struct característiques *aparença;
}

 

Així com les variables d'instància dels objectes declarats estàticament estan dins de l'abast de la classe (estan aquí perqué bessó està definit en la mateixa classe), un mètode Germa pot activar-lo directament:

- ferUnBessóIndèntic
{
    if ( !bessó ) {
        bessó = [[Germà alloc] init];
        bessó->gènere = gènere;
        bessó->aparènça = aparença;
    }
    return twin;
}

 

L'Abast de les Variables d'Instància

Encara que estan declarades en la interfície de la classe, les variables d'instància són més una manera de formar en que una classe s'implementa que la forma en que s'utilitza. La interfície d'objecte es bassa en els seus mètodes, no en les seves estructures de dades internes.

Sovint, hi han una correspondència un-a-un entre un mètode i una variable d'instància, com en l'exemple següent:

- (BOOL)ésPle
{
    return ple;
}

 

Però aquesta necessitat no és el cas. Alguns mètodes poden retornar la informació no guardada en les variables d'intància, i algunes variables d'instància podrien guardar informació que un objecte no està disposat a revelar.

Així com una classe es revisada cada cert temps, l'elecció de les variables d'instància poden canviar, fins i tot encara que els mètodes mantenen les mateixes declaracions. Així els missatges són el vehicle per interactuar amb les instàncies de les classes, aquests canvis realment no afectarien la seva intefície.

Per reforçar l'abilitat d'un objecte per amagar les seves dades, el compilador limita l'abast de les variables d'instància -- vol dir, que limita la seva visibilitat dins el programa. Però proporciona la flexibilitat, també et permet explícitament assignar l'abast en tres nivells diferents. Cada nivell es marca per una directiva de compilador:

Directiva Significat
@private La variable d'instància només és accesible dins de la classe que la declara.
@protected La variable d'instància és accessible dins de la classe que la declara i dins les classes que l'hereden.
@public La variable d'instància és accessible a tot arreu.

Això s'il·lustra en la Figura 2-4.

Figure 2-4 L'abast de les variables d'instància

Figure 2-4 L'abast de les variables d'instància

Una directiva s'aplica a totes les variables d'instància llistades després d'ella, fins sobre de la següent directiva o al final de la llista. En el següent exemple, les variables d'instància edat i evaluació són privades, nom, feina i salari són protegides, i cap és pública.

@interface Treballador : NSObject
{
    char *nom;
@private
    int edat;
    char *evaluació;
@protected
    id feina;
    float salari;
@public
    id cap;
}

 

Per defecte, totes les instàncies no marcades (com nom) són @protected.

Totes les variables d'intància que una classe declara, no importa que estiguin marcats, estan dins l'abast de la definició de la classe. Per exemple, una classe que declara la variable d'instància job, com la classe Treballador mostra aquí abaix, pot referir-s'hi en la definició del mètode:

- promocionarA:novaPosició
{
    id vell = feina;
    feina = novaPosició;
    return feina;
}

 

Com és obvi, si una classe no pot accedir a les seves pròpies variables d'instància, les variables d'instància podrien no poder-se usar.

Normalment, una classe també té accés a les variables d'instància de que hereda. L'abilitat de referir-se a una variable d'instància és normalment heredada al llarg abm la variable. Això dona sentit per les classes que tenen totes les seves estructures de dades dins al seu abast, especialment si penses en una definició de classe merament com una elaboració de les classe de les que hereda. El mètode promocionarA: mostrat abans podria estar igualment definit en qualsevol classe de la que hereda la variables d'instància feina de la classe Treballador.

Tanmateix, hi han raons per les quals podries voler restringir la herència de classes amb l'accés directe a una variable d'instància:

  • Una en els accessos en subclasses una variable d'instància heredada, la classe que declara la variable està lligada a part de la seva implementació. En versions posteriors, no pot eliminar la variable o alterar el rol que aquest juga sense trencar la subclasse sense adonar-se'n.
  • A més, si uns accessos de subclasse d'una variable d'instància heredada i alterar el seu valor, pot sense voler introduir errors en la classe que declara la variable, especialment si la variable està envoltada en dependències internes de la classe.

 

En un altre exemple, el marcar una variable @public la fa generament disponible, fins i tot fora de les definicions de la classe que hereden o declaren la variable. Normalment, per obtindre informació guardada en un variable d'instància, altres objectes han d'enviar un missatge requerint-lo. Encara uqe, una variable d'intància pública pot accedir-se des de tot arreu com si fors un camp en una estructura C.

Treballador *ceo = [[Treballador alloc] init];
ceo->cap = nil;

 

Fixeu-vos que l'objecte ha de ser declarat estàticament.

Marcant variables d'instància @public elimina l'abilitat d'un objecte a amagar les seves dades. Això engega un contador a un principi fonamental de la programació orientada a objectes -- la encapsulació de les dades dins els objectes on aquesta està protegida de mirades i errors inadvertits. Les variables d'instància públiques, tanmateix, haurien d'evitar-se excepte en casos extraordinaris.

pàgina generada en: 0.606 segons.