学习OC前须知
一、面向对象思想
面向对象
解决问题需要哪些对象
将功能封装进对象,强调具备了功能的对象
面向过程
强调的是功能行为
解决问题需要哪些步骤
完成需求时:
先要去找具有所需的功能的对象来用。
如果该对象不存在,那么创建一个具有所需功能的对象。
这样简化开发并提高复用。
面向对象的核心就是对象,那怎么创建对象?
OC中的类相当于图纸,用来描述一类事物
OC中的类相当于图纸,用来描述一类事物
OC中的类相当于图纸,用来描述一类事物
因此面向对象解决问题应该是先考虑需要设计哪些类,再利用类创建多少个对象
二、OC中的类
OC中用类来描述事物的属性和行为
属性:对应类中的成员变量。
行为:对应类中的成员方法。
定义类其实在定义类中的成员(成员变量和成员方法)
OC中定义一个类也分为声明和实现, 也就是说以后我们在OC中定义类, 就是在写类的声明和实现
1.如何编写类的声明
以@interface开头 , 以@end结尾, 然后再class name对应的地方写上 事物名称, 也就是类名即可
注意: 类名的首字符必须大写
声明一个类的目的就是为了告诉系统, 我们这个类中有哪些属性和行为
// 类名后面的 :NSObject 是为了让我们的Iphone类具备创建对象的能力
@interface Iphone : NSObject
{
// 注意: 默认情况下, OC对象中的属性是不能直接访问的
@public // 只要让类中的属性公开, 以后就可以直接通过一个指向结构体的指针来操作对象中的属性
float _model; // 型号 0
int _cpu; // cup 0
double _size; // 尺寸 0
int _color; // 颜色 0
}
// 行为
@end
OC类声明中属性只能在写@interface和@end之间的{}中
注意: 编写OC类属性的时, 建议将所有属性的名称前面都加上_
2.如何编写类的实现
以@implementation开头, 以@end结尾, 然后在class对应的地方写上声明时声明的类的名称, 必须和声明的类名一模一样
@implementation Iphone
// 行为的实现
@end
3.如何通过一个类来创建对象
在OC中想要通过一个类来创建一个对象, 必须给类发送一个消息(好比C语言中调用函数一样)
如何发送消息? 在OC中只要想要发送消息就先写上 [类名称/对象名称 方法名称];
发送什么消息(调用什么方法)可以创建一个对象呢? new
4.创建对象,系统做的3件事
只要通过一个类调用类的new方法, 也就是给类发送一个叫做new的消息之后
系统内部就会做3件事情
1). 为Iphone类创建出来得对象分配存储空间
2). 初始化Iphone类创建出来的对象中的属性
3). 返回Iphone类创建出来的对象对应的地址
通过一个Iphone类型的指针接收了 Iphone对象的地址
如果使用给一个指针保存了某一个对象的地址, 那么我们就称这个指针位之为某个类型的对象
利用Iphone类型的指针保存了Iphone对象的地址, 那么我们就称Iphone类型的指针p之为Iphone对象
三、OC中的方法
注意: 如果声明的是对象方法那么就必须实现对象方法
如果声明的是类方法那么就必须实现类方法
类方法和对象方法的区别
0. 对象方法以-开头
类方法以+开头
1. 对象方法必须用对象调用
类方法必须用类来调用
2. 对象方法中可以直接访问属性(成员变量)
类方法中不可以直接访问属性(成员变量)
3. 类方法和对象方法可以进行相互调用
4.1对象方法中可以直接调用类方法
4.2类方法中间接调用对象方法 (注意: 不建议这样使用)
4.3类方法中可以直接调用其它类方法
4.4对象方法中可以直接调用对象方法
类方法的应用场景
如果方法中没有使用到属性(成员变量), 那么能用类方法就用类方法
类方法的执行效率比对象方法高
类方法一般用于定义工具方法
字符串查找
文件操作
数据库操作
OC中的行为和C语言中的函数一样, 都是用来保存一段特定功能的代码
C语言中定义一个函数, 分为声明和实现, 声明写在.h中, 实现写在.c中
OC中定义一个方法, 也分为声明和实现, 声明写在@interface中, 实现写在@implementation
C语言的函数分为两种: 内部函数和外部函数
OC中的方法也分为两种; 类方法和对象方法
类方法只能用类名调用, 对象方法只能用对象调用
OC中的类方法用+表示, OC中的对象方法用-表示
编写C语言函数的规律: 1.确定函数名称 2.确定形参 3.确定返回值 4.确定返回值类型
编写OC方法也有规律, 规律和C语言一模一样
注意: OC中的方法, 如果没有形参不需要写(), 而是直接写一个;
为什么OC中没有形参不需要写()呢? 因为OC方法中的()有特殊的用途, OC方法中的()是用来扩住数据类型的
四、面向对象的三大特性
1.面向对象三大特性
- 封装性
- 继承性
- 多态性
2.什么是封装
- 封装性就是隐藏实现细节,仅对外公开接口。
3.为什么要进行封装?
- 以下代码存在的问题?
1成员变量是public的,也就是公开的,我们不能控制外界如何赋值, 外界有可能赋值一些脏数据
@interface Gun : NSObject
{
@public// 公开成员变量
int _bulletCount;// 子弹数量
}
@end
可以利用封装来解决这个问题
封装:是指隐藏对象的属性和实现的细节,仅对外提供公共的访问方法
- 类是数据与功能的封装,数据就是成员变量,功能就类方法或对象方法
- 对数据的封装,也就是对成员变量的封装
- 不封装的缺点:当一个类把自己的成员变量暴露给外部的时候,那么该类就失去对该成员变量的管理权,别人可以任意的修改你的成员变量。
- 封装就是将数据隐藏起来,只能用此类的方法才可以读取或者设置数据,不可被外部任意修改是面向对象设计本质。这样降低了数据被误用的可能性 ,提高代码的灵活性!
4.封装的好处
好处
将变化隔离
提高安全性
原则
将不需要对外提供的内容都隐藏起来,把属性都隐藏,提供公共的方法对其访问
OC中的继承
- B类继承A类,那么B类将拥有A类的所有属性和方法,此时我们说A类是B类的父类,B类是A类的子类
- C类继承B类,那么C类将拥有B类中的所有属性和方法,包括B类从A类中继承过来的属性和方法,此时我们说B类是C类的父类,C类是B类的子类
注意:
1.基类的私有属性能被继承,不能在子类中访问。
2.OC中的继承是单继承:也就是说一个类只能一个父类,不能继承多个父类
3.子类与父类的关系也称为isA(是一个)关系,我们说 子类isA父类,也就是子类是一个父类,比如狗类继承动物类,那么我们说狗isA动物,也就是狗是一个动物。在如汽车继承交通工具,那么们说汽车isA交工工具,也就是汽车是一个交通工具
3.OC中如何实现继承
在声明子类的时候,在子类名称后面通过:父类名称方式来实现继承
// 其实在类名的后面加上: NSObject, 就是让当前类继承NSObject类
// new方法就是继承过来的
// isa指针
// 继承的语法 @interface 类名 : 需要继承的类
//@interface Iphone : NSObject
@interface Iphone : Phone
/*
{
int _cpu;
}
// 打电话
- (void)signalWithNumber:(NSString *)number;
// 发短信
- (void)sendMessageWithNumber:(NSString *)number andContent:(NSString *)content;
*/
继承相关特性知识点:
1. 方法重写
2. 继承中方法调用的顺序
3. 继承的注意事项
1. 方法重写
#import <Foundation/Foundation.h>
#import "Phone.h"
@interface Iphone : Phone
{
// 注意: 在继承中方法可以重写, 但是属性(成员变量)不能重写
// int _cpu;
}
- (void)setCpu:(int)cpu;
- (int)cpu;
// 打电话
// 如果子类中有和父类中同名的方法, 那么我们称之为方法重写
2. 继承中方法调用的顺序
// 注意: 继承中的方法调用顺序, 如果自己有就调用自己的, 如果自己没有就调用父类的
// 方法的调用顺序, 先自己再父类, 如果父类中没有再爷爷类, 如果爷爷类再没有就找爷爷的爸爸类
// 如果一直找到NSObject类都没有找到, 那么就会报错
// reason: '-[Iphone signalWithNumber:]: unrecognized selector sent to instance 0x1003043c0'
- (void)signalWithNumber:(NSString *)number;
// 在继承中除了对象方法可以重写, 类方法也可以重写
+ (void)brand;
@end
3. 继承的注意事项
继承:
当B类继承A类, 那么B类就拥有A类所有的属性和方法(类方法/对象方法)
优点:
提高代码的复用性
可以让类与类之间产生关系, 正是因为继承让类与类之间产生了关系所以才有了多态
注意:
不要以为继承可以提高代码的复用性, 以后但凡发现多个类当中有重复代码就抽取一个父类
只要满足一定的条件我们才能使用继承
条件: XXXX 是 XXX / 某某某 is a 某某某
缺点:
耦合性太强(依赖性太强)
OC类支持单一继承,不支持多继承;也就是说一个类只能有一个直接父类
OC类支持多层继承
1.什么是多态?
什么是多态:多态就是某一类事物的多种形态
程序中的多态:父类指针指向子类对象
2.多态的条件
有继承关系
子类重写父类方法
父类指针指向子类对象
表现:当父类指针指向不同的对象的时候,通过父类指针调用被重写的方法的时候,会执行该指针所指向的那个对象的方法
3.多态的优点
多态的主要好处就是`简化了编程接口。它允许在类和类之间重用一些习惯性的命名,而不用为每一个新的方法命名一个新名字。这样,编程接口就是一些抽象的行为的集合,从而和实现接口的类的区分开来。
多态也使得代码可以分散在不同的对象中而不用
试图在一个方法中考虑到所有可能的对象。 这样使得您的代码扩展性和复用性更好一些。当一个新的情景出现时,您无
须对现有的代码进行 改动,而只需要增加一个新的类和新的同名方法。
1.如何实现多态
Animal是父类,子类有Cat 和 Dog,子类分别重写了父类中的eat方法;实例化对象的时候可以用下面的方法
强制类型转换,后面可用id类型可避免强制类型转换,但需判断。
Animal *animal = nil;
//实例化猫的对象
animal = [Cat new];
[animal eat];
//实例化狗的对象
animal = [Dog new];
[animal eat];
2.多态的原理
动态绑定:
动态类型能使程序直到执行时才确定对象的真实类型
动态类型绑定能使程序直到执行时才确定要对那个对象调用的方法
OC不同于传统程序设计语言,它可以在运行时加入新的数据类型和新的程序模块:动态类型识别,动态绑定,动态加载
id类型:通用对象指针类型,弱类型,编译时不进行具体类型检查
3.多态的注意点
1)如果存在多态,父类是可以访问子类特有的方法
假设 子类 Dog 有一个特有的方法bark
[dog bark];
Animal *an2 = [Dog new];
[(Dog*)an2 bark]; //把父类的指针,强制类型转换
2)如果不存在多态,父类是不可以访问子类特有的方法的