/*
多态
1.没有继承就没有多态
2.代码的体现:父类类型的指针指向子类对象
3.好处:如果函数\方法参数中使用的是父类类型,可以传入父类、子类对象
4.局限性:
1> 父类类型的变量不能直接调用子类特有的方法和成员。必须强转为子类类型变量后,才能直接调用子类特有的方法
*/
#pragma mark
一个类包括.m .h
成员变量的访问(直接通过变量名)权限
@public : 在任何地方都能直接访问对象的成员变量
@private : 只能在当前类的对象方法中直接访问 (@implementation中默认是@private,implementation中可以定义变量(没有interface只有implementation也可以开发一个类),因为implementation文件(.m)一般不被其他文件import,因此变量不可见,也就不存在访问的情况。)
@protected : 可以在当前类及其子类的对象方法中直接访问(@interface中默认就是@protected)
@package : 只要处在同一 个框架中,就能直接访问对象的成员变量
@interface和@implementation中不能声明同名的成员变量
id d=[oc对象 new] (将新对象的地址赋值给指针变量) 指向对象的指针类型,等于NSObject *,利用它可以定义一个指向某个对象的指针变量
typedef struct objc_object{
Class isa; //objc_object是一个对象的结构,包含isa指针
}* id;
[d 对象方法] //id类型的变量不能用点语法
在implementation中重写原始init()
- (id) init{
if(self=[super init]){
成员变量初始化;
}
return self;
}
[类 new]==[[类 alloc] init]
在interface和implementation自定义带参数的inintwithXX()
- (id)initWithName:(NSString *)name andAge:(int)age
{
if ( self = [super init] )
{
_name = name;
_age = age;
}
return self;
}
Student *p = [[Student alloc] initWithName:@"Jim" andAge:29 andNo:10];
有时候我们重写父类的init方法时不注意将init后面的第一个字母写成了小写,在这个方法里面又调用父类的初始化方法(self = [super init];)时会报错,错误信息如下:
原因:只能在init方法中给self赋值,Xcode判断是否为init方法规则:方法返回id,并且名字以init
java当中的增加新功能怎么实现的?
➢ 如何在不改变原来类模型的前提下,给类扩充一些方法?有2种方式
继承 (需要下转型)
分类(Category)
@interface 类名 (分类名称)
// 方法声明
@end
@implementation 类名 (分类名称)
// 方法实现
@end
3. 好处
➢ 一个庞大的类可以分模块开发
➢ 一个庞大的类可以由多个人来编写,更有利于团队合作
➢ Category可以访问原始类的实例变量,但不能添加变量,只能添加方法。如果想添加变量,可以考虑通过继承创建子类
➢ Category可以实现原始类的方法,但不推荐这么做,因为它是直接替换掉原来的方法,这么做的后果是再也不能访问原来的方法
➢ 多个Category中如果实现了相同的方法,只有最后一个参与编译的才会有效
类似Java中得toString()
使用NSLog和%@(输出对象)输出某个对象时,会调用对象的-description方法,并拿到返回值进行输出
使用NSLog和%@输出某个类对象时,会调用类对象+description方法,并拿到返回值进行输出
3. 修改NSLog的默认输出
l 重写-description或者+description方法即可
4. 死循环陷阱
l 如果在-description方法中使用NSLog打印self
block变量(有点像函数指针)
int (^sumBlock)(int, int)=
^(int a, int b) {
return a + b;
};
void (^myBlock)()=
^() {
NSLog(@"----------");
};
* block内部可以访问外面的变量
* 默认情况下,block内部不能修改外面的局部变量
* 给局部变量加上__block关键字,这个局部变量就可以在block内部修改
4> 利用typedef定义block类型
typedef int (^MyBlock)(int, int);
// 以后就可以利用MyBlock这种类型来定义block变量
MyBlock b1, b2;