面向对象和面向过程
OC是面向对象的,C是面向过程的。面向对象和面向过程只是解决问题的两种不同思想。
一、面向对象和面向过程的区别
1) 以用电脑听歌为例子
a) 面向过程
打开电脑
播放电脑中的歌曲
关闭电脑
b) 面向对象(不是相亲的“对象”)
电脑
开机
播放歌曲
关机
2) 区别分析
面向过程关注的是解决问题需要哪些步骤;面向对象关注的是解决问题需要哪些对象。
二、类和对象的关系
1. OC中的面相对象
1) OC中的类相当于图纸,用来描述一类事物。也就是说,要想创建对象,必须先有类
2) OC利用类来创建对象,对象是类的具体存在因此,面向对象解决问题应该是先考虑需要设计哪些类,再利用类创建多少个对象。
2. 需要设计哪些类,如何设计类
1) 类的设计,只关心3样东西(以人为例):
事物名称(类名):人(Person)
属性:身高(height)、年龄(age)
行为(功能):跑(run)、打架(fight)
2) 一般名词都是类
坦克发射3颗炮弹轰掉了2架飞机 (类: 坦克,炮弹,飞机)
小明在公车上牵着一条叼着热狗的狗 (类:小明,公车,热狗,狗)
三、定义OC的类和创建OC对象
1、假设想要创建一辆车出来,首先要有一个车子类,然后利用车子类创建车子对象。
2、描述OC中的类分2大步骤:类的声明、类的实现(定义)。
下面举个例子来加深理解。
创建一个车子对象
(一)类的声明
#import<Foundation/Foundation.h>
@interface Car : NSObject
{
@public
int wheels; // 轮子个数
double speed; // 车子速度
}
-(void)run; // 跑的行为
@end
解释几个名词
1.成员变量
1>@interface的大括号{}中声明的变量:wheels、speed
2>@interface的大括号和函数的大括号是不一样的
3>默认会初始化为0
2.@public
@public可以让Car对象的wheels和speed属性被外界访问
3.NSObject
加上:NSObject的目的是让Car类具备创建对象的能力
(二)类的实现
@implementation Car
-(void) run
{
NSLog(@“%d个轮子,%f时速的车子跑起来了”,wheels,speed);
}
@end
有了类的声明和实现,就可以创建对象
(三)创建对象
int main()
{
Car *c = [Car new];
C->wheels = 3;
C->speed = 300;
[c run];
return 0;
}
代码分析:
1.[Car new]每次都会创建出新的对象,并且返回对象的地址,那么就应该用一个指针变量保存对象的地址
Car *c = [Car new];
用一个指针变量c指向内存中的Car对象
2.设置车子对象的属性
跟用指向结构体的指针访问结构体属性一样,用->
c->wheels = 3;
c->speed = 300;
四、在类的声明,实现过程中,经常会犯的错误
1.只有类的声明,没有类的实现
2.漏了@end
3.@interface和@implementation嵌套
4.两个类的声明嵌套
5.成员变量没有写在括号里面
6.方法的声明写在了大括号里面
五、OC方法和函数的区别
1.C方法只能声明在@interface和@end之间,只能实现在@implementation和@end之间。也就是说OC方法不能独立于类存在
2.C函数不属于类,跟类没有联系,C函数只归定义函数的文件所有
3.C函数不能访问OC对象的成员
六、方法
1. 不带参数的方法
声明
-(double)pi;
实现
-(double)pi
{
return 3.14;
}
方法调用
2. 带一个参数的方法
声明
-(double)ssquare:(double)number;
实现
-(double)square:(double)number
{
return number * number
}
方法调用
3. 带多个参数的方法
设计一个计算和的方法
声明
- (double)sumOfNum1:(double)num1 andNum2:(double)num2;
实现
- (double)sumOfNum1:(double)num1 andNum2:(double)num2
{
return num1 + num2;
}
方法调用
4. 方法名注意
1.冒号也是方法名的一部分
2.同一个类中不允许两个对象方法同名
七、set方法和get方法
1.set方法和get方法的使用场合
@public的成员可以被随意赋值,应该使用set方法和get方法来管理成员的访问(类似机场的安检、水龙头过滤,过滤掉不合理的东西),比如僵尸的生命值不能为负数。
1. set方法
1) 作用:用来设置成员变量,可以在方法里面过滤掉一些不合理的值
2) 命名规范:
方法都是以set开头,而且后面跟上成员变量名,成员变量名的首字母必须大写
形参名称不要跟成员变量同名
2. get方法
1) 作用:返回对象内部的成员变量
2) 命名规范:get方法的名称一般就跟成员变量同名
3. 成员变量的命名规范
成员变量都以下划线 _ 开头
可以跟get方法的名称区分开
可以跟其他局部变量区分开,一看到下划线开头的变量,肯定是成员变量。
代码示例
#import <Foundation/Foundation.h>
声明
@interface Car : NSObject
{
int _wheels; // 轮子个数
}
set方法
- (void) setWheels:(int)wheels;
get方法
- (int) wheels;
@end
@implementation Car
set方法的实现
- (void) setWheels:(int)wheels
{
// 对外面传进来的轮子数进行过滤
if (wheels<=0)
{
wheels = 1;
}
_wheels = wheels;
}
get方法的实现
- (int) wheels
{
return _wheels;
}
@end
4. 封装的好处
1.过滤不合理的值
2.屏蔽内部的赋值过程
3.让外界不必关注内部的细节
八、类方法
1. 基本概念
直接可以用类名来执行的方法(类本身会在内存中占据存储空间,里面有类\对象方法列表)
2. 类方法和对象方法对比
1) 对象方法
以减号-开头
只能让对象调用,没有对象,这个方法根本不可能被执行
对象方法能访问实例变量(成员变量)
2) 类方法
以加号+开头
只能用类名调用,对象不能调用
类方法中不能访问实例变量(成员变量)
使用场合:当不需要访问成员变量的时候,尽量用类方法
3) 类方法和对象方法可以同名
九、继承
1. 继承的基本用法
设计两个类Bird、Dog
Bird的声明
@interface Bird : NSObject
{
@public
int weight;
}
- (void)eat;
@end
Bird的实现
@implementation Bird
- (void)eat {
NSLog(@"吃吃吃-体重:%d", weight);
}
@end
Dog的声明
@interface Dog : NSObject
{
@public
int weight;
}
- (void)eat;
@end
Dog的实现
@implementation Dog
- (void)eat {
NSLog(@"吃吃吃-体重:%d", weight);
}
@end
有相同的属性和行为,抽出一个父类Animal(先抽取weight属性,再抽取eat方法)
Animal的声明
@interface Animal : NSObject
{
@public
int weight;
}
- (void)eat;
@end
Animal的实现
@implementation Animal
- (void)eat {
NSLog(@"吃吃吃-体重:%d", weight);
}
@end
子类在父类的基础上拓充属性和方法
Bird的声明
@interface Bird : Animal
{
@public
int height;
}
- (void)fly;
@end
Bird的实现
@implementation Bird
- (void)fly {
NSLog(@"飞飞飞-高度:%d", height);
}
@end
Dog的声明
@interface Dog : Animal
{
@public
int speed;
}
- (void)run;
@end
Dog的实现
@implementation Dog
- (void)run {
NSLog(@"跑跑跑-高度:%d", speed);
}
@end
子类方法和属性的访问过程:如果子类没有,就去访问父类的
父类被继承了还是能照常使用的
父类的静态方法
画继承结构图,从子类抽取到父类
NSObject的引出:全部OC类的最终父类,包含了一些常用方法,比如+new
2. 继承的专业术语
父类\超类 superclass
子类 subclass\subclasses
3.继承的细节
单继承
子类和父类不能有相同的成员变量
方法的重写
3. super关键字
分别调用父类的对象方法和类方法
4. 继承的好处
1.不改变原来模型的基础上,拓充方法
2.建立了类与类之间的联系
3.抽取了公共代码
坏处:耦合性强
5. 继承的使用场合
它的所有属性都是你想要的,一般就继承
它的部分属性是你想要的,可以抽取出另一个父类
十、多态
1.多态的基本概念
某一类事物的多种形态
OC对象具有多态性
2.多态的体现
Person *p = [Student new];
p->age = 100;
[p walk];
子类对象赋值给父类指针
父类指针访问对应的属性和方法
3.多态的好处
1.用父类接收参数,节省代码
4.多态的局限性
不能访问子类的属性(可以考虑强制转换)
5.多态的细节
动态绑定:在运行时根据对象的类型确定动态调用的方法