#import <Foundation/Foundation.h>
@interface ClassA : NSObject
{
int _x;
}
@property int x;
-(void) initVar;
-(void) initVar:(int)v;
@end
#import "ClassA.h"
@implementation ClassA
@synthesize x=_x;
-(void) initVar
{
self.x=100;
}
-(void) initVar:(int)v
{
self.x=v;
}
@end
上面这种写法是之前使用最多也是最传统的写法 它将实例变量和属性在形式上区别 实例变量以_开头 而属性不以_开头 实例变量写在接口部分或实现部分 @synthesize之中将实例变量赋值给属性 如果不这样做 将会出现两个实例变量 即属性本身@synthesize生成的实例变量x以及接口部分声明的_x self.x=100、self.x=v用实力变量写就是_x=100、_x=v
#import <Foundation/Foundation.h>
@interface ClassA : NSObject
@property int x;
-(void) initVar;
-(void) initVar:(int)v;
@end
#import "ClassA.h"
@implementation ClassA
@synthesize x;
-(void) initVar
{
self.x=100;
}
-(void) initVar:(int)v
{
self.x=v;
}
@end
这种写法是我们平时一般的写法 实例变量和和属性在形式上没有区别 self.x=100、self.x=v用实力变量写就是x=100、x=v
#import <Foundation/Foundation.h>
@interface ClassA : NSObject
@property int x;
-(void) initVar;
-(void) initVar:(int)v;
@end
#import "ClassA.h"
@implementation ClassA
-(void) initVar
{
self.x=100;
}
-(void) initVar:(int)v
{
self.x=v;
}
@end
这种是苹果推荐的写法 省略@synthesize 编译器会自动生成以_开头的实例变量(可能在文件中看不到实例变量 但确实存在) 和第一种写法效果一样 不同之处只是不需要在接口部分或实现部分声明实例变量 self.x=100、self.x=v用实力变量写就是_x=100、_x=v
总结一下实例变量和属性
实例变量在接口部分声明 公有 子类可以直接继承实例变量 在实现部分声明 私有 子类无法继承
@property的作用就是声明属性 声明了属性必定有相应的实例变量与之对应 说白了属性就是实例变量的存取方法 没有声明属性的实例变量 必须自己编写存取方法 否则无法使用.运算符 并且在编写存取方法内部也无法使用self.x 因为此时并没有实例变量的存取方法
@synthesize的作用就是生成实例变量 生成和属性相同或以_开头的实例变量
根据后两种方法写的子类如下
#import "ClassA.h"
@interface ClassB : ClassA
@property int y;
-(void) printVar;
-(int) initVar;
-(int) initVar:(int)v;
@end
#import "ClassB.h"
@implementation ClassB
@synthesize y;
-(void) printVar
{
NSLog(@"x=%i",self.x);
}
-(int) initVar
{
self.x=300;
return self.x;
}
-(int) initVar:(int)v
{
self.x=v;
return self.x;
}
@end
#import "ClassB.h"
@interface ClassC : ClassB
-(void) printVar;
-(double) initVar;
-(double) initVar:(double)v;
@end
#import "ClassC.h"
@implementation ClassC
-(void) printVar
{
NSLog(@"y=%i",self.y);
}
-(double) initVar
{
self.y=500;
return self.y;
}
-(double) initVar:(double)v
{
self.y=v;
return self.y;
}
@end
B类只能使用self和.运算符对x操作 C类也只能使用self和.运算符对x、y操作 因为他们并没有从父类的接口部分继承实例变量 所有只能使用属性操作
感觉苹果想把实例变量隐藏起来 能用属性操作的尽量使用属性来操作 这样self就显得异常重要 当然有的情况下还是得使用实例变量 比如一个类的实例变量是另一个类的对象时 这点后面再讲
从上面可以看到-(void) initVar和-(void) initVar:(int)v是两个不同的方法 而之后用不同的参数和返回值覆写了这两个方法 由此可见 同一个方法名 带与不带参数是两个不同的方法 而不同的参数和返回值 确实是同一种方法 顺带提一下 参数和返回值的类型是 参数在传入之后和返回值在传出之后的类型 而NSLog函数和scanf函数的类型是在传入和传出之前要求