Objective-C-私人,受保护与公共 [英] Objective-C - Private vs Protected vs Public

查看:90
本文介绍了Objective-C-私人,受保护与公共的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望在使用Objective-C进行编程时对私有成员,受保护成员和公共成员相对于类成员的工作方式进行澄清-我以为我知道其中的区别(我已经向父类Person添加了一些有关相同),但是当我尝试通过子类访问私有ivar/父类成员时,编译器没有抱怨的事实使我感到困惑.

I am hoping for some clarification on how Private vs Protected vs Public works with respect to class members when programming in Objective-C - I thought I knew the difference (I've added some comments to my parent class Person with respect to the same), but the fact that the compiler did not complain when I tried to access a private ivar/member of a parent class via the subclass now has me confused.

这是我的家长班:

/*
 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

这是我的派生类Man:

    /*
     Man - Subclass of Person
    */

    #import <Foundation/Foundation.h>
    #import "Person.h"

    @interface Man : Person
    {
        //iVar for Man
        float mWeight;
    }
    @property float mWeight;

    @end

最后,这是主要内容:

#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;
        }

编译器应该不会抱怨为什么我尝试访问上面的aMan.yob吗?或使用@property& @synthesize(即setter和getter方法)实际上已使该成员受到保护,因此子类可以访问它?

Shouldn't the compiler complain why I try to access aMan.yob above? Or by using @property & @synthesize (i.e. the setter and getter methods) have I essentially made that member protected and therefore accessible to the subclass?

推荐答案

可见性不会影响方法.当对客户可见时,这些方法与公共方法一样好(当对客户不可见时,潜在的陷阱/错误).相反,可见性会影响实例变量.试试这个:

visibility does not affect methods. methods are as good as public when visible to clients (and potential pitfalls/bugs when invisible to clients). instead, visibility affects instance variables. try this:

#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;
        }

这可以防止子类直接访问ivars-迫使它们和客户端使用访问器(如果提供).

this prevents the subclasses from accessing ivars directly -- forcing them and clients to use the accessors (if provided).

这有点薄弱,因为类别允许客户克服这一点.

this is all a bit weak because categories allow clients to overcome this.

此外,较旧的32位objc程序并没有真正检查可见性是否已正确声明.幸运的是,该功能已在32中弃用,在64中已出现错误.

also, older 32 bit objc programs did't really check that the visibility was declared correctly. fortunately, that's been deprecated in 32 and an error in 64.

如果您确实希望某些东西对子类和类别私有,请使用未发布/不透明类型的PIMPL.

if you really want something to be private to subclasses and categories, use PIMPL with an unpublished/opaque type.

方法可见性(在Java,C ++等中可以找到)是我在objc中使用的功能.

method visibility (as found in Java, C++, etc.) is a feature i'd use in objc.

这篇关于Objective-C-私人,受保护与公共的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆