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  空的对象(Object) (id)0
NULL  空指针 (void *)0
Nil  (Class)0   (Void *)0
NSNull  [(NSNull)null]
   

 向nil发送消息的返回值

返回id型  nil
返回指针   NULL
返回整数 0
其他

根据Max OS X版本,构造体大小等不同

具体不确定

   

 

 类型的静态确认

 用明确的类去声明变量时,呼出该类不存在的东西时警告

 ●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
  @private

@protected

@interface内部默认

@public
 在类的定义内部(直接指定名字)
 该类的实例变量(->) ×
 子类 ×
 子类的实例变量(->) × ×
 任何地方 × ×

 可以在@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]; //这么写

这样的话被继承了也可以在子类直接用

   
posted @ 2018-01-21 02:20  懒虫哥哥  阅读(143)  评论(0编辑  收藏  举报