正文
#1、实例变量修饰符
(1)、public:可以在本类中被访问到,也可以在其他类中被访问到,当然,在子类中也能被访问到;
(2)、private:可以在本类中被访问到,但是不可以在其他类中被访问到,在子类中也同样不可以被访问到;
(3)、protected:可以在本类中被访问到,但是不可以在其他类中被访问,然而在子类中却是可以被访问到,
没有写明修饰符的默认情况下的实例变量都是用protected修饰的
;
(4)、package:介于public和private之间
如果是在当前所在包以外,则是private,其在子类中是不可以被访问的;
如果是在当前所在包以内,则是public,其在子类中是可以被访问的。
**
不管是用什么修饰符修饰的,我们都可以在其他类中查看这个类的属性,但是有些修饰符修饰的属性我们是不能操作的,但是,在**
@implement{
//定义属性,修饰符任意
}
@end
**这个属性也是私有属性,但是这个在外界是看不到的,而private定义的属性可以看到,例:
**
//情形一
Person:NSObject{
@private
int _age;
}
Person *p = [Person new];
p->age; //这里只有warning
//情形二
@implementation Person{
int _age;
}
Person *p = [Person new];
p->age; //这里会报错
//情形三
@implementation Person{
@public
int _age;
}
Person *p = [Person new];
p->age; //这里还是会报错
#2、私有“方法”与公有“方法”(OC中只有消息,没有方法)
如果只有方法的实现,没有方法的声明,那么这个方法就是私有方法,但是OC没有真正意义上的私有方法:
@implementation Person{
int _age;
}
-(void)test {
NSLog(@"age = %@",_age);
}
@end
//其他类里面
Person p = [Person new];
[p test]; //报错,访问不到test
id p = [Person new];
[p test]; //这里会打印->age = 0;
//或者
Person p = [Person new];
[p performSelector:@selector(test)];//这里也会打印->age = 0;
#3、@property与@synthesize
(1)、@property是一个编译器指令,使用它我们可以代替setter和getter方法的
声明
,因此我们可以省去自己编写setter和getter方法声明;
(2)、@synthesize也是编译器指令,用来生成setter与getter方法的
实现
;
**PS:
a、后期的@property已经同时具有声明和实现setter和getter方法的功能,如果有
@property int num;
那么他会自动找到以 _ 开头同名的*成员变量进行赋值,即:
@property int num;
等价于
@property int num = _num;
;
b、如果我们自己重写了setter与getter方法,那么编译器不会自动帮我们生成这两个方法;
c、我们可以不写成员变量的声明,并且我们没有同时重写setter和getter方法(可以重写其中一个),如方法一所示,系统会自动为我们生成一个带 _ 的成员变量,但是它是一个私有变量,只能在本类中使用;
**
下面三个写法是等价的:
//写法一
@interface Person
@property int age;
@end
@implementation Person
@end
//写法二
@interfae Person{
int _age;
}
-(void)setAge:(int)age;
-(int)age;
@end
@implementation Person
-(void)setAge:(int)age {
_age = age;
}
-(int)getAge{
return _age;
}
@end
//写法三
@interface Person{
int _age;
}
@property int age;
@end
@implementation Person
@synthesize age = _age; //这句不能写在@interface里面
@end
注意
如果不是按照标准写法,@synthesize property = _property;的写法,而是@synthesize property;那么生成的setter与getter方法会是如下:
@interface Person{
int _age; //a
int age; //b
}
@property int age;
@end
@implementation Person
@synthesize age;
/*
等价于
-(void)setAge:(int)age {
age(b行的age)= age(形参age); //而非_age = age;
}
-(int)age{
return age;//而非return _age;
}
*/
@end
#4、description方法:
description方法是系统自带的方法,用来打印一个类或者一个对象的所有成员变量的信息,但是我们可以重写这个方法,来输出我们需要的内容。
Person *p = [Person new];
NSLog(@"%@",p); //自动调用系统内的-(NSString *)description; 方法
Class *c = [p class];
NSLog(@"%@",c);//自动调用系统内的+(NSString *)description; 方法
综上,打印对象自动调用对象方法,打印类会调用类方法。
注意:在重写对象description方法的时候,不能用%@输出self,否则会造成死循环。
-(NSString *)description {
NSLog(@"%@",self); //死循环,这里输出会调用description方法
return