ultima tutorial objective logo español objective-c

objective c - tutorial - Objetivo-C: Privado vs Protegido vs Público



objective c vs c++ (4)

El truco habitual es crear una extensión de clase dentro del archivo .m y poner allí su propiedad privada / protegida en lugar de en el encabezado.

//Person.m @interface Person() @property float height @end

esto oculta la propiedad ''altura''

Otro truco es si quieres crear una propiedad de solo lectura declararla en el encabezado como

@property(readonly) int myproperty

pero en la extensión de clase como readwrite que le permite a su .m modificar el valor usando el getter / setter

@property(readwrite) int myproperty

Espero algunas aclaraciones sobre cómo funciona Privado vs Protegido vs Público con respecto a los miembros de la clase cuando se programa en Objective-C: pensé que sabía la diferencia (he agregado algunos comentarios a mi clase padre Persona con respecto a la misma) , pero el hecho de que el compilador no se quejara cuando intenté acceder a un ivar / miembro privado de una clase padre a través de la subclase ahora me tiene confundido.

Aquí está mi clase para padres:

/* Person.h */ #import <Foundation/Foundation.h> @interface Person : NSObject { //We can also define class members/iVars that are of type private //This means they can only be accessed by the member functions //of the class defining them and not subclasses @private int yob; //We can also define class members/iVars that are of type public //Public members can be accessed directly @public bool alive; //By default class members/iVars are of type protected //This means they can only be accessed by a class''s own //member functions and subclasses of the class and typically //also by friend functions of the class and the subclass //We can explicitly define members to be protected using the //@protected keyword @protected int age; float height; } @property int age; @property float height; @property int yob; @property bool alive; @end

Aquí está mi clase derivada Hombre:

/* Man - Subclass of Person */ #import <Foundation/Foundation.h> #import "Person.h" @interface Man : Person { //iVar for Man float mWeight; } @property float mWeight; @end

Y finalmente, aquí está el principal:

#import <Foundation/Foundation.h> #import "Person.h" #import "Man.h" int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; //Create a Person object Person * aPerson = [[Person alloc]init]; //Create a Man object Man * aMan = [[Man alloc]init]; //Let''s attempt to modify our Person class members aPerson.height = 5.11; //Protected aPerson.age = 21; //Protected aPerson.yob = 2010; //Private aPerson.alive = YES; //Public //Let''s now attempt to modify the same members via our //derived class Man - in theory, the private members should //not be accessible by the derived class man aMan.height = 6; //Protected aMan.age = 26; //Protected aMan.yob = 2011; //Private aMan.alive = YES; //Public aMan.mWeight = 190; //Protected member of Man Class [pool drain]; return 0; }

¿No debería el compilador quejarse por qué trato de acceder a aMan.yob arriba? O al usar @property & @synthesize (es decir, los métodos setter y getter), ¿he hecho que ese miembro esté protegido y, por lo tanto, accesible para la subclase?


Está configurando las visibilidades de los ivars, no las propiedades. Sus propiedades generan métodos public getter y setter.

Para crear propiedades privadas, puede colocar las propiedades en una categoría privada en el archivo .m.


No está accediendo a los miembros: está accediendo a la propiedad en Person que no tiene el nivel de acceso especificado.


la visibilidad no afecta los métodos. los métodos son tan buenos como públicos cuando son visibles para los clientes (y posibles peligros / errores cuando son invisibles para los clientes). en cambio, la visibilidad afecta las variables de instancia. prueba esto:

#import <Foundation/Foundation.h> #import "Person.h" #import "Man.h" int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; //Create a Person object Person * aPerson = [[Person alloc]init]; //Create a Man object Man * aMan = [[Man alloc]init]; //Let''s attempt to modify our Person class members aPerson->height = 5.11; //Protected aPerson->age = 21; //Protected aPerson->yob = 2010; //Private aPerson->alive = YES; //Public //Let''s now attempt to modify the same members via our //derived class Man - in theory, the private members should //not be accessible by the derived class man aMan->height = 6; //Protected aMan->age = 26; //Protected aMan->yob = 2011; //Private aMan->alive = YES; //Public aMan->mWeight = 190; //Protected member of Man Class [pool drain]; return 0; }

esto impide que las subclases accedan directamente a los ivars, lo que los obliga a ellos y a los clientes a usar los accessors (si se proporcionan).

todo esto es un poco débil porque las categorías permiten a los clientes superar esto.

Además, los programas anteriores objc de 32 bits realmente no verificaron que la visibilidad se haya declarado correctamente. afortunadamente, eso ha quedado obsoleto en 32 y un error en 64.

si realmente desea que algo sea privado para las subclases y categorías, use PIMPL con un tipo no publicado / opaco.

la visibilidad del método (como se encuentra en Java, C ++, etc.) es una característica que usaría en objc.