Objective-C类和对象总结:
头文件.h文件:(header file)
类的声明:@interface 类名字 : 父类的名称
类名的约定:1、首字母大写,比如Person
父类:通常是NSObject,我们也可以自己指定父类。
类的声明是@end作为结束符。
源文件.m文件(source file):放属性、方法的具体实现。
实现的结构:
#import “xxx.h”//导入类声明的头文件
@implementation 类名称
…….属性和方法的具体实现...........
@end//以@end作为结束符
成员变量:
一个实体所具有的特征
声明:
成员变量必须包括在大括号重
@interface 类名:父类名称
{
//在这个大括号里面,声明成员变量
}
@private、@protected 、@public用于控制成员变量的可访问性(访问权限)
@private 私有成员==》只允许当前类访问
@protected 受保护的成员==》允许当前类和子类进行访问。
默认就是protected(声明成员变量的时候,不指定默认就是@protected)
@public 公共成员====》所有的类都能够访问。
成员变量的约定:
Objc里面,所有的对象类型的变量都必须使用指针,也就是除了基本的数据类型(int,char,float,double,BOOL)之外的变量,都需要使用指针。
比如:一个类的实体,结构体,数组。
在ObjC中不管是自定义的类还是系统类对象都必须是一个指针
定义好了一个类之后,我们进行实例化的时候,有两个步骤:
1)、分配内存===》alloc
2)、对实体进行初始化===》init
推荐实例化的写法:
类名称 *变量名=[[类名称 alloc] init];
方法分类:
1)静态方法 用+定义
2)动态方法 用-定义
定义方法的格式:
无参数:
+/- (返回值类型) 方法名称;
有一个参数的时候,参数前面需要冒号:
+/- (返回值类型) 方法名称 : (参数的类型)参数名称;
如果有多个参数,我们在第二个参数以后的参数之前,加一个参数说明,方便我们调用的时候,快速的了解方法里面参数的含义
+/- (返回值类型) 方法名称:(参数的类型)参数名称 第二个参数的说明:(第二个参数的类型)第二个参数的名称..........
如果没有在.h中声明,而是直接在.m中定义则该方法是私有方法,外部无法访问。私有方法只允许在当前源文件中调用。其它的类无法访问。
调用静态方法和动态方法的区别:
静态方法:只允许使用类名称进行调用
动态方法:只允许在类里面(在类的源文件中直接调用)或者是通过实例化的对象去调用
属性:通常都是通过对应的setter或者是getter方法进行实现的。
约定:setter方法通常是在属性名称前加一个set,getter方法通常是直接使用属性名称(不加get)
Objc的点语法:
指针变量名称.属性名称
点语法具体到是调用setter方法还是调用getter方法,取决于当前的操作是赋值还是读取
赋值(=)的时候就是调用setter方法,读取的时候调用getter方法。
@property和@synthesize关键字:
我们定义属性的代码基本是一致的,我们使用@property和@synthesize自动生成getter、setter方法。
- 如果只声明一个属性a,不使用@synthesize实现:编译器会使用_a作为属性的成员变量(如果没有定义成员变量_a则会自动生成一个私有privated的成员变量_a;如果已经定义了成员变量_a则使用自定义的成员变量_a。注意:如果此时定义的成员变量不是_a而是a则此时会自动生成一个成员变量_a,它跟自定义成员变量a没有任何关系);
- 如果声明了一个属性a,使用@synthesize a进行实现,但是实现过程中没有指定使用的成员变量(例如上面birthday):则此时编译器会使用a作为属性的成员变量(如果定义了成员变量a,则使用自定义成员变量;如果此时没有定义则会自动生成一个私有的成员变量a,注意如果此时定义的是_a则它跟生成的a成员变量没有任何关系);
- 如果声明了一个属性a,使用@synthesize a=_a进行实现,这个过程已经指定了使用的成员变量:此时会使用指定的成员变量作为属性变量;
self关键字:不仅可以表示当前对象还可以表示类本身
self可以调用动态方法和静态方法
self的实质:指针===》这个指针是指向当前的调用者。
self就代表当前方法的调用者
构造方法:
默认的构造方法是init,继承自NSObject这个类。
我们可以使用自己的构造方法(传参数等)
id类型:
id类型可以代表所有的类型(自己定义的类或者系统定义的类),大多数情况下,也是一个指针。
id类型在运行的时候,才能确定具体的类型。
运用id的地方:通常是返回一个类的实例化的对象(指针)的时候
super关键字:代表父类。
使用super关键字的时候,是直接调用父类的方法的。
即便是子类重写了相同的方法,super调用的,也是父类的方法。
description方法:
定义在NSObject
我们使用%@输出的时候,就会调用description方法。(使用%@的地方不限于NSLog)
重写description方法,通常是按照一定的格式,答应类的成员变量或者属性。
重写的description,严格禁止直接打印self(引起死循环)
默认情况下如果我们不重写description方法,输出内容是类名和地址,例如Person则输出“<Person: 0x100202310>”。
继承:
继承是可以递归的:比如B继承自C,A也可以继承自B A===>B====>C
Objc不允许多继承:也就是我们声明类的时候,不允许在冒号后写多个类的名字,因为Objc只能允许单集成。
子类:可以直接访问父类成员变量(private的不允许),属性
子类可以调用父类的公开的方法
子类也可以复写父类的公开的方法。
子类和父类的成员变量:
子类和父类成员变量是独立的,子类的实体修改了成员变量的值,不会父类,父类修改了成员变量的值,也不会影响子类。子类和父类,即便是成员变量有继承关系,但是他们都是独立的。
类调用方法:
首先,在当前类,查找被调用的方法,如果当前类,实现了被调用的方法,就会直接调用当前类的方法。
如果当前类,没有实现被调用的方法,程序会自动向上查找直接父类,如果在父类里面定义了被调用的方法,就会调用父类的方法,。
如果父类还找不到被调用的方法,程序会再次向上查找,一直查到NSObject。
最终如果查找到NSObject(Objc的基类),都没有找到方法的定义,这个时候编译器会报错。
使用super关键字,调用的是这个类的直接父类中的方法。如果父类中找不到被调用的方法,程序向上级的父类进行查找,一直到NSObject为止。
宏定义:
#define 宏定义名称 字符串(不需要使用@“”包住)
作用:用到宏定义的地方,编译器会自动的把宏定义名称右边的字符串整个的复制。
BOOL类型:值有两个YES和NO,实质上BOOL是一个unsigned char,YES的值是1,NO的值为0.
oc里面,进行逻辑比较的时候(if语句等)同样遵守C语言的规范:
非0值为真,0值为假。
SEL变量:
SEL:是方法的唯一ID。同名的方法ID相同。
我们可以通过如下几种方式取得SEL变量的值:
1、@selector(方法名)
2、NSSelectorFromString(@“方法名”)
通过SEL变量调用方法的格式:
[对象 performSelector:SEL变量 withObject:参数1 withObject:参数2];
函数指针:
指向函数的指针变量。
定义函数指针,有两种方式。
1、跟C语言函数指针类似
2、使用IMP,使用IMP定义函数指针的时候,需要将xcode的编译参数:enable strict Checking of objc_msgSend Calls设置为NO,调用的时候才能正确编译。
Class类型:
通过一个普通的字符串取得一个类的定义。
Class类型的变量取得了类的定义之后,就可以认为,我们这个Class变量是一个已知的类。
就可以实例化对象、进行方法调用等操作。
1 Class 变量名 = [类或者对象 class];
2 Class 变量名 = [类或者对象 superclass];
3 Class 变量名 = NSClassFromString(方法名字的字符串);
特殊方法:
[对象 className]:返回的是对象的类名称
[对象 respondsToSelector : SEL变量名]:判断对象是否具有SEL变量所指向的函数。如果没有SEL变量所指向的这个函数,返回值为NO