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