------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
1.self和super
OC提供了两个保留字self和super,用于在方法定义中引用执行该方法的对象。
OC语言中的self,就相当于C++、Java中的this指针。
学会使用self,首先要搞清楚属性这一概念。
设置器与访问器,提供外界操作类内部属性的一个通道。
因为类的属性,默认是@protect(受保护类型)。属性一般是私有的。
super发送消息可以将方法实现分发其父类。可以重写一个已有的方法来修改或将它添加到现有的方法中,仍然可以将原始的方法纳入到修改后的方法当中。
self的应用场景:
1)用在类方法中
2)用在对象方法中
3)访问成员变量
4)self在OC的内存管理特殊使用
self在对象方法中使用其指代的是调用当前方法的对象。
self在类方法中使用其指代的是当前类。
elf在对象方法中可以利用self->属性名称的方式访问成员变量。
self使用总结:
- self 谁调用当前方法,self就代表谁
- self在对象方法中,self代表当前对象
- self在类方法中个,self代表类
- [self 方法名称]; 调用其它方法(类方法/对象方法)
- self可以简单理解为指自己
同时有对象方法和类方法存在的时候,self不会调错。
2.类的继承和派生概念
继承是指一个对象直接使用另一对象的属性和方法。
@interface Animal : NSObject{
int age;
}
-(void)run;
@end
@interface Dog :Animal{
}
-(void)LookHome;
@end
一般来说,派生类的方法属性 = 基类的属性方法 + 派生类自己新增的方法属性
1)基类的私有属性能被继承,不能被使用。
2)OC中的继承是单继承:也就是说一个类只能一个父类,不能继承多个父类
3)继承的合理性:
方法的重写,从父类继承的方法,可能这个方法并不适合子类,可以在子类中重写父类的方法。
重写之后,父类的对象调用父类的方法;子类的对象,调用子类的方法,不会引起冲突。
从父类继承的方法,不适用于子类时,可以直接声明父类的同名方法,并定义。
不用考虑父类中方法已存在的问题。
重写后,子类可以通过super调用父类的方法。
继承的注意事项:
1)子类不能定义和父类同名的变量,但是可以继承父类的变量
2)OC类支持单一继承,不支持多继承
3)OC类支持多层继承
继承体系中方法调用的顺序:
1、在自己类中找
2、如果没有,去父类中找
3、如果父类中没有,就去父类的父类中
4、如果父类的父类也没有,就还往上找,直到找到基类(NSObject)
5、如果NSObject也没有就报错了
3.实例变量的修饰符
@public 任意的程序集
@protect 同类和派生类
@private 同类
1)@public (公开的)在有对象的前提下,任何地方都可以直接访问。
2)@protected(受保护的)只能在当前类和子类的对象方法中访问。
3)@private(私有的)只能在当前类的对象方法中才能直接访问。
4)@package (框架级别的)作用域介于私有和公开之间,只要处于同一个框架中就可以直接通过变量名访问。
变量的修饰符在子类中访问:
1)@private私有成员是能被继承,不能被外部函数访问。
2)@public公有成员能被继承,也能被外部方法访问。
3)@protected保护成员能够被继承、在子类中使用,但不能够被外部函数访问。
实例变量作用域使用注意事项:
(1)在@interface @end之间声明的成员变量如果不做特别的说明,那么其默认是protected的。
(2)一个类继承了另一个类,那么就拥有了父类的所有成员变量和方法,注意所有的成员变量它都拥有,只是有的它不能直接访问。
4.OC中的私有变量
在类的实现即.m @implementation中也可以声明成员变量,但是因为在其他文件中通常都只是包含头文件而不会包含实现文件,
所以在.m文件中声明的成员变量是@private的。
在.m中定义的成员变量不能和它的头文件.h中的成员变量同名,在这期间使用@public等关键字也是徒劳的。
私有变量既不能看到也不能使用。
OC中的私有(相对私有)方法:
OC中并没有像Java或者其他语言中提供的私有方法,OC中的私有,可以理解为相对私有。
OC中私有方法实现有两种方式:
1)方法在.m中实现,不在.h中声明(相对私有)
2)通过匿名类别实现私有(一般意义上的私有)
@interface MyClass {
// 添加变量
}
-(void)PublicMethod;//公共方法,可以被继承类继承
@end
而在类的.m文件中,采用类别来实现私有方法,具体操作为:
@interface MyClass()//注意(),即定义一个空类别
-(void)PrivateMethod;//在类别中定义私有方法
@end
5.description方法的介绍和重写
descriptong方法默认返回对象的描述信息(默认实现是返回类名和对象的内存地址)。
description方法是基类NSObject所带的方法,因为其默认实现是返回类名和对象的内存地址,这样的话,
使用NSLog输出OC对象,意义就不是很大,因为我们并不关心对象的内存地址,比较关心的是对象内部的一些成变量的值。
因此,会经常重写description方法,覆盖description方法的默认实现。
千万不要在对象description方法中同时使用%@和self,下面的写法是错误的:
-(NSString *)description {
return [NSString stringWithFormat:@"%@", self];
}
同时使用了%@和self,代表要调用self的description方法,因此最终会导致程序陷入死循环,循环调用description方法。
6.多态的概念
多态指的是:同一种行为,对于不同的事物具有不同的表现形式。这就叫做多态。
现实生活中多态的特点:
1).在老师的眼里,他们三个我只当做人来看待。
2).三个人具有共同的行为,但是他们每1个人的这个行为的实现是不一样的。
3).给他们发送这个指令然后每1个人按照自己的实现方式去做。
程序中的多态:不同的对象以自己的方式响应相同名称方法的能力称为多态。
多态的条件:
有继承关系、有方法重写。
父类的声明变量指向子类对象。
多态的主要好处就是简化了编程接口。
它容许在类和类之间重用一些习惯性的命名,而不用为每一个新加的函数命名一个新名字。
这样,编程接口就是一些抽象的行为的集合,从而和实现接口的类的区分开来。
多态也使得代码可以分散在不同的对象中而不用试图在一个函数中考虑到所有可能的对象。
这样使得您的代码扩展性和复用性更好一些。当一个新的情景出现时,您无须对现有的代码进行改动,而只需要增加一个新的类和新的同名方法。
动态类型能使程序直到执行时才确定对象所属类型
动态类型绑定能使程序直到执行时才确定要对对象调用的实际方法
OC不同于传统程序设计语言,它可以再运行时加入新的数据类型和新的程序模块:动态类型识别,动态绑定,动态加载
注意:
1)如果存在多态,父类是可以访问子类特有的方法。
2)如果不存在多态,父类是不可以访问子类特有的方法的。
7.类的本质
类的本质其实也是一个对象(类对象)。
类对象:
类对象再程序运行时一直存在。
类对象是一种数据结构,存储类的基本信息:类大小,类名称,类的版本以及消息与函数的映射表等
类对象所保存的信息在程序编译时确定,在第一次使用该类的时候被加载到内存中。
类对象代表类,class代表类对象,类方法属于类对象
如果消息的接收者是类名,则类名代表类对
运行时,所有类的实例都由类对象生成,类对象会把实例的isa的值修改成自己的地址,每个实例的isa都指向该实例的类对象,
从类对象里可以知道父类信息、可以响应的方法等
类对象只能使用类方法,不能用实例方法
8.SEL类型
SEL类型,全称为selector,是一种用来表示方法名的数据类型。
SEL类型作用:
1)可以定义变量
2)可以用来作为方法的形参
3)可以用来作为方法的实参
类中方法存储的原理:
1)类里面的方法都是被转换成SEL变量进行存储的。
2)当类声明一个对象,对象调用方法的时候,系统会把这个方法转换成SEL,然后拿这个SEL到类方法中去匹配。
Person*p=[[Personalloc]init];
[ptest];
寻找方法的过程:
(1)首先把test这个方法名包装成SEL类型的数据;
(2)根据SEL数据找到对应的方法地址;
(3)根据方法地址调用相应的方法。
(4)注意:在这个操作过程中有缓存,第一次找的时候是一个一个的找,非常耗性能,之后再用到的时候就直接使用。
SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去寻找对应的方法地址,
找到方法地址后就可以调用方法。这些都是运行时特性,发消息就是发送SEL,然后根据SEL找到地址,调用方法。