• Català
  • Castellano
  • English


Definició Estàtica


Si un punter a una nom de classe s'utilitza en lloc de id en una declaració d'objecte,

Rectangle *aquestObjecte;

el compilador restringeix el valor de la variable declarada per ser cap més instància de la classe anomenada en la declaració o una instància d'una classe que hereda de la classe anomenada. En el exemple anterior, aquestObjecte només pot ser un Rectangle o algun tipus de Rectangle.

Els objectes definits estàticament tenen les mateixes estructures internes de dades com els objectes declarats per ser id's. La definició no afecta a l'objecte; només afecta al conjunt d'informació donada al compilador sobre l'objecte i el conjunt d'informació disponible a aquella llegida al codi font.

La definició estàtica tampoc afecta a com l'objecte es tractat a l'hora de l'execució. Els objectes definits estàticament estan assignats dinàmicament pels mateixos mètodes de la classe que crea instàncies de tipus id. Si el Quadrat és una subclasse de Rectangle, el codi següent encara podria produir un objecte amb totes les variables d'intància d'un Quadrat, no només aquelles d'un Rectangle:

Rectangle *aquestObjecte = [[Quadrat alloc] init];

Els missatges enviats a objectes definits estàticament són enllaçats dinàmicament, igual que els objectes de tipus id. El tipus exacte d'un receptor definit estàticament es determina en temps d'execució com a part del procés de missatgeria. Un missatge dibuixa enviat a aquestObjecte

[aquestObjecte dibuixa];

executa la versió del mètode definit en la classe Quadrat, no la de la seva superclasse Rectangle.

Al donar al compilador més informació sobre un objecte, la definició estàtica obre noves possibilitats que no hi son per objectes de tipus id:

  • En certes situacions, aquest permet la comprovació de tipus a l'hora de compilar.
  • Pit alliberar objectes de la restriicció que mètode anomenats idènticament tinguin retorns i arguments de tipus idèntic.
  • Et permet utilitzar l'operador del punter de la estructura per accedir a una variable d'instància d'objecte.

Els primer dos punts es discutiran en les següent seccions. El tercer és cobert a "Definint una Classe".

Comprovació de Tipus

Amb la informació adicional proporcionada per la definició estàtica, el compilador pot repartir millor els serveis de comprovació de tipus en dues situacions:

  • Quan un missatge s'envia a un receptor definit estàticament, el compilador pot assegurar que el receptor pot respondre. Una advertència es mostra si el receptor no té accés al mètode anomenat en el missatge.
  • Quan un objecte definit estàticament s'assigna a una variable definida estàticament, el compilador assegura que els tipus siguin compatibles. Una advertència es mostra si no ho són.

Un assignament pot fer-se sense advertències, proporcionant la classe de l'objecte assignat identicament, o heredatm la classe de la variable receptor de l'assignament. El següent exemple il·lustra això:

Forma     *unaForma;
Rectangle *unRectangle;

unRectangle = [[Rectangle alloc] init];
unaForma = unRectangle;

Aquí unRectanglepot assignar-se a unaForma perqué un Rectangle és un tipus de Forma -- la classe Rectangle hereda de Forma. Tanmateix, si els rols de les dues variables estan reservats a unaForma s'assigna a unRectangle, el compilador genera una advertència; no qualsevol Forma és un Rectangle. (Per referencies, mireu Figura 2-2, la qual mostra la jerarquia de classe incloent-hi la Forma i el Rectangle).

No hi han comprovacions quan la expressió en qualsevol costat de l'operador d'assignament és un id. Un objecte definit estàticament pot ser assignat lliurement a un id, o un id a un objecte definit estàticament. Perqué els mètodes com alloc i init retornen ids, el compilador no assegura que un objecte compatible serà retornat a una variable definida estàticament. El següent codi és un error propens, però tanmateix està permés:

Rectangle *unRectangle;
unRectangle = [[Forma alloc] init];

Tipus de Retorns i Arguments

En general, els mètodes de classes diferents que tenen el mateix selector (el mateix nom) també han de compartir el mateix tipus de retorn i tipus d'arguments. Aquesta restricció està imposada pel compilador per permetre l'enllaçat dinàmic. Perquè la classe d'un receptor de missatge (i per tant els detalls específics de la classe sobre el mètode són preguntats a l'executar-se), no poden conneixer-se a l'hora de compilar. el compilador ha de tractar tots els mètodes amb el mateix nom. Quan aquest prepara informació sobre el retorn del mètode i els tipus d'arguments pel sistema d'execució, aquest crea una descripció del mètode per cada selector de mètode.

Tanmateix, quan un missatge s'envia a un objecte definit estàticament, la classe del receptor és conegut pel compilador. El compilador té accés a la informació específica de la classe sobre els mètodes. Per tant, el missatge està lliure de les restriccions dels seus tipus d'arguments i retorn.

Definició Estàtica a una Classe Heredada

Una instància pot estar definida estàticament per la seva pròpia classe o per qualsevol classe que hi hereda. Totes les instàncies, per exemple, poden estar definides estàticament com a NSObjects.

Tanmateix, el compilador enten que la classe d'un objecte només definit estàticament des del nom de la classe en la designació de tipus, i això fa que el seu tipus segons la comprovació. Definint una instància a una classe heredada pot, per tant donar com a resultat a discrepàncies entre el que el compilador pensa que podria succeir en temps d'execució i que passa realment.

Per exemple, si defineixes estàticament una instància de Rectangle com una Forma,

Forma *elMeuRectangle = [[Rectangle alloc] init];

el compilador el tractarà com una Forma. Si envies a l'objecte un missatge per executar un mètode del Rectangle,

BOOL solid = [elMeuRectangle esPle];

el compilador es queixarà. El mètode esPle està definit a la classe Rectangle, no a la Forma.

Tanmateix, si li envies un missatge per executar un mètode que la classe Forma conneix,

[elMeuRectangle dibuixa];

el compilador no podrà queixar-se, encara que el Rectangle sobreescrigui el mètode. En temps d'execució, la versió del mètode del Rectangle s'executarà.

De forma semblant, suposa que la classe Superior declara un mètode problema que retorna un double,

- (double)problema;

i la subclasse Mitja de Superior sobreescriu el mètode i declara un nou tipus de retorn:

- (int)problem;

Si una instància esta declarada estàticament en la classe Superior, el compilador pensarà que el seu mètode problema retorna un double, i si una instància ñes definida de classe Mitja, pensarà que problema retorna un int. Obviament, els error es produiran si una instància Mitja es definida en una classe Superior. El compilador informarà al sistema d'execució que un missatge problema enviat a un objecte retorna un double, però a l'hora d'executar-se retornarà un int i genera un error.

La definició estàtica pot alliberar mètodes anomenats d'igual forma per la restricció en que han de tenir idèntics tipus de retorns i arguments, però això només pot ser rentable si els mètodes estan declarats en diferents brànques de la jerarquia de classes.