Objective-C 对象的类型与动态结合
创建: 2018/01/21
更新: 2018/01/22 标题前增加 [Objective-C]
完成: 2018/01/24
更新: 2018/01/24 加红加粗属性方法的声明 [不直接获取内部属性,获取用变量名,设定在变量名前加set]
更新: 2018/01/27 加红加粗类对象型Class, 首字母要大写
动态结合(多态) | |||||||||||||||||||||||||
动态结合 |
呼出同一个方法,根据呼出方不同执行的处理也不同
//--------------------------------------------------------------------- // 类型定义 //--------------------------------------------------------------------- //动态结合与多态 @interface S4_A : NSObject { } - (void)getLocationOfHierarchy; - (void)getLocationOfHierarchy:(BOOL)isneedHello; @end @interface S4_B : S4_A { } - (void)getLocationOfHierarchy; //重载 - (void)getLocationOfHierarchy:(BOOL)isneedHello; //重载 @end //--------------------------------------------------------------------- // 类定义 //--------------------------------------------------------------------- //动态结合与多态 @implementation S4_A - (void)getLocationOfHierarchy { puts("this is A"); } - (void)getLocationOfHierarchy:(BOOL)isneedHello { if (isneedHello) { puts("hello, this is A"); } else { puts("need no hello, this is A"); } } @end @implementation S4_B - (void)getLocationOfHierarchy { puts("this is B"); } - (void)getLocationOfHierarchy:(BOOL)isneedHello { if (isneedHello) { puts("hello, this is B"); } else { puts("need no hello, this is B"); } } @end //--------------------------------------------------------------------- // 测试函数 //--------------------------------------------------------------------- void S4Tester(void) { puts("-----------------------------------------"); puts(" S4"); puts("-----------------------------------------"); id aTemp = [[S4_A alloc] init]; [aTemp getLocationOfHierarchy]; [aTemp getLocationOfHierarchy:NO]; [aTemp getLocationOfHierarchy:YES]; id bTemp = [[S4_B alloc] init]; [bTemp getLocationOfHierarchy]; [bTemp getLocationOfHierarchy:NO]; [bTemp getLocationOfHierarchy:YES]; } 运行结果 ----------------------------------------- S4 ----------------------------------------- this is A need no hello, this is A hello, this is A this is B need no hello, this is B hello, this is B Program ended with exit code: 0
|
||||||||||||||||||||||||
多态 |
多态就是动态结合 优点: 不用对每一个具体对象改变现有代码 p60 |
||||||||||||||||||||||||
数据类型与类 | |||||||||||||||||||||||||
用型名来声明,定义 |
// 写法 类名 *变量名 //例 S4_A *a1, *a2, *a3; 是指针参照,改一个其他参照相同的都会改 |
||||||||||||||||||||||||
空指针nil |
alloc把所有设为0,id和指针设为nil
向nil发送消息的返回值
|
||||||||||||||||||||||||
类型的静态确认 |
用明确的类去声明变量时,呼出该类不存在的东西时警告 ●id型来声明的, 不会检查类型。呼出不存在的东西也不报错。 不能用->来获取变量 ●id型和具体型可以互相代入 ●实际运行时呼出的函数是实际包含在对象内的,而不是代码上看起来的 ●id型不是(NSObject*), 和其他类没有继承关系
|
||||||||||||||||||||||||
编程的类型声明 | |||||||||||||||||||||||||
signature不同的情况 |
信息选择器带上返回值类型,参数类型的叫signature //信息选择器 sample: sample_1; //signatrue - (int)sample:(int)a (id)sample_1:a; signature由NSMethodSignature管理 # TODO: Supply [15-05 NSMethodSignature相关] 结论: 同一信息选择器应该设为同样的signature,也就是数据类型相同 |
||||||||||||||||||||||||
类的前置声明 |
可以代替#import来说明该字符串是类名 要带; @class Sample; 只是说明这是个类,不能呼出内部的方法
|
||||||||||||||||||||||||
重写 | 运算符的多重定义 | ||||||||||||||||||||||||
变形 |
和c一样的写法 (型)变量; //例子 int a = 0; (float) a = 1.1; id a; (SampleObject) a;
|
||||||||||||||||||||||||
实例变量的封装 |
|||||||||||||||||||||||||
获取/设定都用方法 |
不直接获取内部属性,获取用变量名,设定在变量名前加set
@interface Sample { int sampleVar; } - (int) samplevar; //获取sampleVar - (void) setSampleVar:(int)var; //设定sampleVar @end
|
||||||||||||||||||||||||
修改内部实例变量 的接入权限 |
@private @private // 只在当前类可以 @protected @protected // 只在当前类内部 // 当前类的变量 // 子类内部可以获取 @public @public //任何地方都可以获取内部变量 @package @package //该类所在框架内部相当于@public // 框架外如同@private
可以在@implementation内声明变量(默认@private) @interface Sample : NSObject { @public int publicNum; @protected int protectedNum; @private // 不指定的话默认都是这个 int privateNum; } - (void)test: (int)selector; @end @implementation Sample { int privateA; //@implementation部分声明的变量默认@private @public int publicA; //可以手动改变权限,和@interface部分写法一样 } - (void)test: (int)selecter { ... } @end
|
||||||||||||||||||||||||
类对象 (class object) | |||||||||||||||||||||||||
类对象是什么 |
面向对象语言里把类也看做对象的语言(Obj-C, smalltalk), 不算做对象的(C++等) Obj-C里有类方法(如alloc),没有类变量
|
||||||||||||||||||||||||
类对象的型 |
Class, 空的值是Nil 获取类的方法就是class [SampleClass class]; // 获取类的class类型 Sample *a = [[Sample alloc] init]; [a class]; // 获取实例对象的class类型
判断是不是指定类的实例 [ctemp isMemberOfClass: [S4_C class]]
|
||||||||||||||||||||||||
定义类方法 |
+ (返回值类型)方法选择器; + (int)getCount: (int *)array; 可以和实例方法及实例变量重名 注意: ●不能在类方法里呼出实例变量,实例方法 ●self表示的是自己的类,呼出其他类方法直接对self发送 [self classMethod]; ●呼出父类的类方法用super [super classMethodFromSuperClass];
|
||||||||||||||||||||||||
类变量 |
●变量前加上static,因为static的量在其他文件处不可见 ●把参照和设置函数设成类方法
|
||||||||||||||||||||||||
类的初始化 |
●类的初始化在该类第一次获取消息(收到函数)时自动发生 ●NSObject的初始化方法initialize ●在初始化类对象时,父类的构造函数会自动呼出。不需要自己呼出父类的构造函数
static char *S4_Str = "还没初始化"; @interface S4_C : S4_B { + (void)initialize; @end @implementation S4_C + (void)initialize { S4_Str = "S4_C 已初始化"; puts(S4_Str); } @end ●只初始化类什么都不做,用self self类方法定义在NSObject [S4_C self]; // S4_C 已初始化
|
||||||||||||||||||||||||
构造函数返回值的类型 |
都用id ●因为继承,如果不是id,受父类返回的类型 ●在类内部呼出自己的类方法时候 [[Sample alloc] initWithParrern: 1]; // 不这么写 [[[self class] alloc] initWithParrern: 1]; //这么写 这样的话被继承了也可以在子类直接用 |
||||||||||||||||||||||||