1)@public (公开的)包含@protected的作用范围;并且在有对象的前提下,任何地方都可以直接访问。
(2)@protected (受保护的)只能在当前类和子类的对象方法中访问(在@interface @end之间声明的成员变量如果不做特别的说明,那么其默认是protected的)
(3)@private (私有的)只能在当前类的对象方法中才能直接访问(定义在m文件中的类扩展部分或者是@implementation内)
(4)@package (框架级别的)作用域介于私有和公开之间,只要处于同一个框架中就可以直接通过变量名访问
首先定义三个类,Person类,Children类,Animal类,其中Children类是Person类的子类。
Person类头文件:
#import <Foundation/Foundation.h>
@interface Person : NSObject
{
NSString *name;
@public int age;
@private float wegiht;
}
-(void)setName;
-(void)setAge;
-(void)setWegiht;
@end
Person类m文件:
#import "Person.h"
//在当前类对象的方法中都能访问之前定义的实例变量,无论是@private,@protected,还是@public
@implementation Person
-(void)setName {
name=@"wall";
NSLog(@"%@",name);
}
-(void)setAge {
age=20;
NSLog(@"%d",age);
}
-(void)setWegiht{
wegiht=50;
}
@end
接下来看Children类,也就是Person类子类的头文件和m文件
头文件:
#import "Person.h"
@interface Children : Person
@end
m文件:
#import "Children.h"
//由于name变量是@protected,age变量是@public,wegiht变量是@private ,所以Children类的对象方法中不能访问wegiht变量,而可以访问name变量和age变量
@implementation Children
-(void)setName {
name=@"small wall";
}
-(void)setAge {
age=8;
}
@end
如果访问私有变量wegiht,则会报错:
接下来看main文件:
#import <Foundation/Foundation.h>
#import "Person.h"
#import "Children.h"
#import "Animal.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
//由于age变量是@public,所以在有对象的前提下,是可以直接访问,其他的变量是不可以直接访问的
Person *xiaoming=[[Person alloc]init];
[xiaoming setAge];//此时age=20
xiaoming->age=24;//直接访问public变量
NSLog(@"%d",xiaoming->age);
Children *baobao=[[Children alloc]init];
baobao->age=2;//直接访问public变量
NSLog(@"%d",baobao->age);
}
return 0;
}
@interface部分为类扩展(extension)。
其被设计出来就是为了解决两个问题的,
其一,定义类私有方法的地方。
其二,实现public readonly,private readwrite的property(意思是在h头文件中定义一个属性对外是readonly的,但在类的内部希望是可读写的,所以可以在m源文件中的@interface部分重新定义此属性为readwrite,此时此属性对外是只读的,对内是读写的),虽然是这么说但是实测在xcode10上h头文件中定义一个属性对外是readonly的,.m里面的方法还是可以,原因是自定义了set方法,所以没问题,没的话确实报错。
此外,也可在此部分申明变量和属性,但申明的变量,属性和方法均为私有的,只能够被当前类访问,相当于private。
原文:https://blog.csdn.net/chokshen/article/details/52944648