## 第一讲:OC简介及基本语法
Objective-C简称OC是在C语言的基础上,增加了一层最小的面向对象语法,完全兼容C语言,也就是可以在OC代码中混入C语言代码,甚至是C++代码。可以使用OC开发Mac OS X平台和IOS平台的应用程序。简单的介绍了一下OC,下面我们来看看OC的基本语法,学习OC之前我们先学习了C语言,因为OC是在C语言的基础上的一门开发语言,因此OC的很多基本语法跟使用方法跟C语言有类似的地方但是也有其独特的地方。
#### 1. 关键字
OC中的关键字基本上所有的都是以@开头,但也有少数不是以@开头的,下面是一些较常用的关键字:
@interface、@implementation、@end @public、@protected、@private、@selector @try、@catch、@throw、@finally @protocol、@optional、@required、@class @property、@synthesize、@dynamic self、super、id、_cmd、__block、__strong、__weak、
#### 2. 字符串以@开头
比如@"Hello"是OC中的字符串,而"Hello"则是C语言中的字符串
#### 3. OC程序的开发过程
OC程序的开发跟C语言类似,从 .m源文件编译成 .o目标文件再链接成 a.out可执行文件
#### 4. 程序框架
OC程序的入口也是main函数
在编写第一个OC程序时用到了OC的输出函数NSLog,但调用NSLog需要包含Foundation框架,OC中一般使用#import
其中#import的作用:跟C语言中#include一样,用来拷贝某个文件的内容,#import可以自动防止文件内容被拷贝多次,也就意味着头文件中不用加入相应的预处理指令。
```c
#import
//OC程序的入口:main函数
int main()
{
//printf("第一个OC程序\n");//OC完全兼容C语言程序
NSLog(@"第一个OC程序"); //NSLog输出内容会自动换行
return 0;
}
```
#### 5. NSLog与printf的区别
NSLog接收OC字符串作为参数,printf接收C语言字符串作为参数
NSLog输出后会自动换行,printf输出后不会自动换行
使用NSLog需要
```c
#import
```
使用printf需要
```c
#include
```
#### 6. Foundation框架的作用
开发OC、iOS、Mac程序必备的框架
此框架中包含了很多常用的API(应用编程接口)
框架中包含了很多头文件,若想使用整个框架的内容,包含它的主头文件即可:
```c
#import
```
#### 7. BOOL的使用
BOOL类型的本质 typedef signed char BOOL;
BOOL类型的变量有2种取值:YES、NO
```c
#define YES (BOOL)1
#define NO (BOOL)0
```
BOOL的输出(当做整数来用)
```c
NSLog(@"%d %d", YES, NO);
```
## 第二讲:类和对象
OC是一门面向对象的开发语言,而C语言是面向过程的,因此在开发思想上要把面向过程和面向对象好好区分开来,体会其中的不同之处。面向过程关注的是解决问题需要哪些步骤,而面向对象关注的是解决问题需要哪些对象。
#### 1. 类的设计
在C语言中完整的写一个函数需要函数的声明和定义(也就是实现),而OC中类似,完整的写一个类需要类的声明和实现
类的设计主要包括:类名,属性和行为
设计类名注意点:
- 类名的第一个字母必须是大写
- 不能有下划线
- 多个英文单词,用驼峰标识
#### 2. 方法(行为)的设计
OC中方法就是行为,主要包括方法名,参数,返回值(声明和实现)方法不能放在大括号里面
注意点:
- 只要是OC对象的方法,必须以减号 - 开头,类方法以+开头
- OC方法中任何数据类型都必须要用()扩住
- OC方法中的小括号():只有一个作用,用来扩住数据类型
#### 3. 类的声明跟实现
OC中类的声明值得是用来声明对象的属性跟行为,声明对象的属性(实例变量或者叫成员变量) , 成员变量默认情况下会做一个初始化,所有成员变量默认都是0
声明在@interface和@end之间进行,实现在@implementation和@end之间进行
在使用类创建对象之前,会将类加载进内存,类的内存里面只放方法列表,创建的每个对象内部默认有一个指针(isa指针),这个指针指向这个对象所对应的类,所有的对象共用相同的类里面的方法。
类的声明跟实现常见错误:
- 只有类的声明,没有类的实现
- 漏了@end ,@interface和@implementation嵌套
- 两个类的声明嵌套
- 成员变量没有写在括号里面
- 方法的声明写在了大括号里面
语法细节:
- 成员变量不能在{}中进行初始化、不能被直接拿出去访问
- 方法不能当做函数一样调用
- 成员变量\方法不能用static等关键字修饰,别跟C语言混在一起(暂时忽略)
- 类的实现可用写在main函数的后面,主要在声明后面就行了
#### 4. 方法跟函数的区别
方法:
- 对象方法都是以减号-开头
- 对象方法的声明必须写在@interface和@end之间
- 对象方法的实现必须写在@implementation和@end之间
- 对象方法只能由对象来调用
- 对象方法归类\对象所有
函数:
- 函数能写在文件中的任意位置(@interface和@end之间除外),函数归文件所有,函数可以定义在@implementation和@end之间,这个是没有问题完全可以
- 函数调用不依赖于对象
- 函数内部不能直接通过成员变量名访问某个对象的成员变量
#### 5. 方法的声明和实现
```c
@interface JiSuanQi : NSObject
- (double)pi; // 方法名叫pi,不带参数的方法
// OC方法中,一个参数对应一个冒号
// 方法名叫pingFang: ,要连上冒号,为了防止方法名的冲突,冒号也是方法名的一部分
- (int)pingFang:(int)num; // 带一个参数的方法
// 方法名叫: sumWithNum1:andNum2:
- (int)sumWithNum1:(int)num1 andNum2:(int)num2; // 带两个参数的方法,可读性好 冒号前面加一些描述信息,来描述后面的参数是干嘛用的
@end
```
因此注意在定义方法名时要注意一些规范,保证可读性好,类似于 sumWithNum1:andNum2:这种的方法名。
## 第三讲:三大特性
第三讲我们主要讲OC的三大特性,OC是一门面向对象的语言,面向对象的开发语言一般共同的特点就是具有三大特性:封装,继承和多态。下面我们来学习一下OC的三大特性。
### 一、 封装
封装就是对类中的一些字段,方法进行保护,不被外界所访问到,有一种权限的控制功能。
封装的好处:过滤不合理的值,屏蔽内部的赋值过程,让外界不必关注内部的细节。
#### 1. set方法和get方法
set方法
作用:提供一个方法给外界设置成员变量值,可以在方法里面对参数进行相应过滤
命名规范:
(1)方法名必须以set开头
(2)set后面跟上成员变量的名称,成员变量的首字母必须大写
(3)返回值一定是void
(4)一定要接收一个参数,而且参数类型跟成员变量类型一致
(5)形参的名称不能跟成员变量名一样
get方法
作用:返回对象内部的成员变量
命名规范:
(1)肯定有返回值,返回值类型肯定与成员变量类型一致
(2)方法名跟成员变量名一样
(3)不需要接收任何参数
#### 2. 成员变量的命名规范:一定要以下划线 "_" 开头
作用:
让成员变量和get方法的名称区分开
可以跟局部变量区分开,一看到下划线开头的变量,一般都是成员变量
#### 3. 经典错误
```c
#import
@interface Person : NSObject
@end
@implementation Person
@end
int main()
{
Person *p = [Person new];
// OC是在运行过程中才会检测对象有没有实现相应的方法
[p test];//实现中没有test方法
return 0;
}
```
报错:-[Person test]: unrecognized selector sent to instance 0x7fd2ea4097c0
给Person对象发送了一个不能识别的消息:test
#### 4. 类方法和对象方法
(1)对象方法:
*减号 - 开头
*只能由对象来调用
*对象方法中能访问当前对象的成员变量(实例变量)
(2)类方法:
*加号 + 开头
*只能由类(名)来调用
*类方法中不能访问成员变量(实例变量)
(3)类方法的好处和使用场合:
*不依赖于对象,执行效率高
*能用类方法尽量用类方法
*场合:当方法内部不需要使用到成员变量时,就可以改为类方法
*可以允许类方法和对象方法同名
#### 5. self关键字
self关键字是个指针,self指向方法调用者,代表着当前对象,当成员变量和局部变量同名时,采取就近原则,访问的是局部变量,用self访问成员变量,区分同名的局部变量
self用途:
(1)谁调用了当前方法,self就代表谁,(指向了当前对象-方法调用者)
* self出现在对象方法中,self就代表对象
* self出现在类方法中,self就代表类
(2)在对象方法中利用“self->成员变量名”访问当前对象内部的成员变量
(3)[self 方法名] 调用当前对象的某一个方法,可以调用其他对象方法或者类方法
常见错误:
*低级错误:用self去调用函数
*类方法中用self调用对象方法,对象方法中用self调用类方法
*self死循环
### 二、 继承
继承是类中的一个重要的特性,他的出现使得我们没必要别写重复的代码,可重用性很高。继承的一些专业术语:父类\超类:superclass 子类:subclass\subclasses
#### 1.继承的好处:
*抽取重复代码
*建立了类之间的关系
*子类拥有父类中的所有成员变量和方法
*注意点:基本上所有类的根类是NSObject
#### 2. 方法的重写
重写:子类重新实现父类中的某个方法,覆盖父类以前的做法
注意:
*父类必须声明在子类的前面,实现可以放在子类的后面
*子类不能拥有和父类相同的成员变量
*调用某个方法时,优先去当前类中找,如果找不到,去父类中找
*坏处:耦合性太强:类之间的关系太紧密了,当某个父类不见了,子类就用不了
#### 3. 继承的使用场合
当两个类拥有相同属性和方法的时候,就可以将相同的东西抽取到一个父类中
当A类完全拥有B类中的部分属性和方法时,可以考虑让B类继承A类
#### 4. 继承和组合
当某个类想拥有另一个类当中的东西,考虑两种方式,一种是继承一种是组合
继承:xx 是 xxx 代表什么什么(子类)是什么什么(父类)
组合:xxx 拥有 xxx
```c
类A
{
int _age;
int _no;
}
类B
{
A *_a; // B里面拥有A,这个是组合
int _weight;
}
```
在实际的使用中,要注意逻辑和设计,区分好继承和组合的使用。
#### 5. super关键字
super的作用和使用场合:
*直接调用父类中的某个方法
*super处在对象方法中,那么就会调用父类的对象方法
*super处在类方法中,那么就会调用父类的类方法
*使用场合:子类重写父类的方法时想保留父类的一些行为
### 三、 多态
多态指的是某一类事物的多种形态,OC对象具有多态性
多态的体现:Person *p = [Student new]; p->age = 10; [p walk];
#### 1. 多态的使用注意
*没有继承就没有多态
*代码的体现:父类类型的指针指向子类对象
*好处:如果函数\方法参数中使用的是父类类型,可以传入父类,子类对象
*局限性:父类类型的变量 不能 直接调用子类特有的方法。必须强制转为子类类型的变量后,才能直接调用子类特有的方法。
#### 2. 代码中的注意点
```c
Animal *a = [Dog new];
//[a run];run方法为Dog独有,不能直接访问
Dog *d = (Dog *)a;//强制转换为Dog *类型才能调用run方法
[d run];
```