您的位置:首页 > 职场人生

黑马程序员------OC @property 关键字及构造方法的使用

2015-07-29 23:21 357 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一 、@property 关键字的使用

1.点语法 : 编译器的特性,编译器帮我们做代码替换

在掉用时,set方法[p setAge:19]; [p setName:@"zlz"];

点语法 对象.属性名

注意此时,(对象.属性名)并不是直接访问实例变量,而是xcode看到点语法(p.age)后,会自动替我们生成[p setAge 18]

p.age --替换-->[p setAge: 18]

int a =[p age];//调用get方法 NSString *s = [p name];

注意: 此处p.age是出现在等号右侧

实际上,当xcode 看到 p.age 出现在等号的右侧后,会帮我么把p.age --替换成-->[p age];

int a = p.ag //调用get方法

强调:p.age到底是替换成get 还是set方法,一般取决于p.age 是出现在等号左侧还是右侧(是设置值,还是取值)

注意:点语法的本质是转换成相应的get和set方法,如果没有set 和get方法 ,则不能使用点语法。

2.@property关键字的使用

1.@property的介绍

@property 是编译指令

在4.4之前 @property 告诉编译器 声明属性的访问器(getter 和setter)方法 4.4 之后有增强功能

2.@property的使用

@property的用法 @property 类型名 实例变量名(方法名)

@property int age; 相当于进行了age的set和get方法的声明

- (void)setAge:(int)age;

- (void)age;

3.@synthesize关键字

1.@synthesize 用法

@property int age;@synthesize age ;表示生成.h变量的age的set和set方法的实现

注意:如果@synthesize 变量名要先在.h中声明

@synthesize age 帮我们生成变量age

- (void)setAge:(int)age{

self ->age =age;

}

- (int)age{

return age;

}

2.@synthsize指定实例变量赋值

如果两个实例变量的类型一致 可以 @synthesize age,weight;

指定操作实例变量的@synthesize 方法名 = 实例变量名

当指定实例变量以后,此时再不会操作默认的实例变量

@synthesize age = _age, weight =_weight;

@synthesize name =_name;

3.property 曾强使用

xcode 4.4 之后 只使用@property 可以自动生成和实现setter和getter方法。

@property int age; @orperty NSString* name

这里生成的都是 _age 和 _name;和自己手动设置的get 和set是一致的。。

操作的是下划线的实例变量 ,如果我们当前类并没有下划实例变量,则系统会自动帮我们生成。

生成 int _age; NSString *_name; 实例是私有的。不能被子类看到。

4.@porperty 下重写get和set方法

为了过滤条件。get方法和set方法在.m中可以自己动手实现,

get和set方法不能同时手动实现。

- (void)setAge{

if(age>0){ //年龄是整数才算合理。 这里对set重写。

_age =age;

}else{

_age = 0;

}

}

二、动态类型和静态类型

多态:允许不同的类定义相同的方法。

动态类型: 程序直到执行时才能确定所属的类

静态类型:将一个变量定义为特定的对象时,是静态的。

1.id类型

Animal *ani=[Animal new];

[ani run];动物在跑

Animal *an2 = [Dog new];

[an2 run];狗在跑

NSObject *obj = [Anmal new];

[(Animal*)obj run];//访问子类特有的方法 强制转换

obj = [Dog new];

[(Dog*)obj run];

NSObject是所有类的基类。obj可以指向任何子类

注意 id 的使用

id obj2; NSObject 和id都可以指向对象

obj2 =ani; NSObject对象会进行编译时检查(需要强制类型转换)

[obj2 run]; id不需要强制类型转换,id 可以直接使用

obj2 =dog; 编译器看到id以后,认为是动态类型,不检查类型。

[obj2 run]

2.动态类型检测

1)判断类型

-(BOOL)isKindOfClass:classObj

判断实例对象是否是这个类或者这个子类的实例对象 格式[对象 isKindOfClass: 类对象]

BOOL isInstance = [ani isKindOfClass:[Animal class]]; ani 是Animal的实例

2)-(BOOL)isMemberOfClass:classObj 判断对象是否是指定类的实例对象

格式 [对象 isMemberOfClass:对象]

3)判断是否是指定类的子类(类和类之间的关系)

格式 :类A isSubclassOfClass:类B

+(BOOL) isSub = [ Dog isSubclassOfClass:[Animal class];

4)

判断对象能否响应指定的方法

- (BOOL)respondsToSelector:selecctor 判断实例是否有这样方法能响应run方法

判断,如果 ani 能够调用 eat 方法,然后就调用

SEL s1 =@selector(eat);//把eat包装成SEL类型

BOOL isResspond =[ani respondsToSelector :s1];

判断类中有没有调用指定方法

EL s1 =@selector(eat);

is Respond =[Dog instancesRespondToSelector:s1];

响应方法

Animal*ani =[Dog new];

SEL s1 =@selector(eat);

if([ani respondsToSelector:s1]){

[ani performSelector];//作用,响应方法

}else{

通过performSelector: withObject :响应有参的方法

SEL s2 = @selector(eat);

[ani performSelector:s2 withObject:@"lzl"]

三、构造方法

oc中的构造方法:给对象进行初始化的方法

oc中给对象初始化的方法是:init 该方法是一个对象方法 ,返回的时一个对象(调用init的对象)

oc中的构造方法,主要学习 如何重写构造方法,让对象创建成功后,就有初始值。

[[Person alloc] init] 等价于 [Person new]

1.init 方法就是一个构造方法,是用来初始化对象的方法,注意这是一个对象方法,以减号开头,初始化完毕,所有成员变量的值都为0.

2.alloc 向某个类发送alloc消息 ,为该类分配内存,以存放该类的全部实例变量,还将这块区域全部初始化为0

3.重写构造方法

需求Person 对象创建完成以后 ,年龄默认是10岁

//通过修改默认的构造方法来实现

@importementation Person

//当子类把父类的init覆盖了,这是默认的先执行子类的

- (instancetype)init{

//先让父类把父类原来做的事情完成 判断父类是否初始化成功

if(self = [super init]){

_age =10;//此处写子类的初始化类容 。给年龄设置默认值为 10岁。

}

return self/代指的是方法的调用者

}

#import <Foundation/Foundation.h>

@interface Gun : NSObject
@property int bulletCount;
- (void)shoot;
@end

#import "Gun.h"

@implementation Gun
- (instancetype) init {
if (self =[super init]) {
_bulletCount =3;   //让每把枪都有3颗子弹
}
return self;
}

- (void)shoot{
_bulletCount--;
if(_bulletCount >0){
NSLog(@"正在射击。。。当前子弹还有%d",_bulletCount);
}else{
NSLog(@"每子弹了请换子弹");
}
}
@end
#import "Gun.h"

@interface Solider : Gun
{
Gun* _gun;
}
-(void)fire;
-(instancetype)init;
@end

#import "Solider.h"

@implementation Solider

-(void)fire{
[_gun shoot];

}
-(instancetype)init{
//重写init
if (self =[super init]) {
Gun*  gun = [Gun new]; //创建一个枪对象

_gun= gun;
}
return self;
}
@end
#import <Foundation/Foundation.h>
#import "Gun.h"
#import "Solider.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//创建20个士兵
for(int i =0;i<20;i++){

Solider *s1 =[[Solider alloc] init];

[s1 fire];
}

}
return 0;
}


4.自定义构造方法

一定是对象方法,以减号开头

返回值一般是id类型

方法名 一般以initWith开头。

#import <Foundation/Foundation.h>

@interface Person : NSObject
@property NSString * name ;
@property int age;
- (instancetype)initWith:(NSString*)name andAge:(int)age;
@end
#import "Person.h"

@implementation Person
- (instancetype)initWith:(NSString*)name andAge:(int)age
{
//重写Person的init
if (self = [super init]){
_name = name;
_age  = age;
}
return self ;
}

@end

#import "Person.h"

@interface Student : Person
@property int sno;
- (instancetype)initWith:(NSString*)name andAge:(int)age andSno: (int)sno;
@end
#import "Student.h"

@implementation Student
- (instancetype)initWith:(NSString*)name andAge:(int)age andSno: (int)sno{
//继承父类的init方法、、
if (self =[super initWith:name andAge:(int)age]) {
_sno = sno; //给自己的赋值 学号
}
return self;

}
@end
//Person 类创建成功,给人起一个名字 让后再对年龄进行初始化
// 创建一个学生类 要求 有学号

#import <Foundation/Foundation.h>
#import "Person.h"
#import "Student.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//创建对象 同时指定名字和 年龄
Person *p =[[Person alloc] initWith:@"lzl" andAge:18];

NSLog(@"姓名:%@  年龄%d",p.name,p.age);

Student * stu =  [[Student alloc] initWith:@"zhangsanf" andAge:28 andSno:1];
NSLog(@"姓名:%@  年龄%d  学号%d",stu.name,stu.age,stu.sno);

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: