最近一直在福州出差,前段时间项目也是比较忙,也没空看视频写代码。今天也是到月底了,项目估计还有一周就要结束了,乘着中午有点时间就把面向对象的三大特性总结总结吧。总结的方式依然是以word文档中的内容为框架,中间加些自己做的习题和理解。
面向对象的三大特性:封装、继承、多态
一、封装
什么是封装呢,封装其实也可以理解为成员变量的封装,或者方法的封装。看字面的意思就能明白,封装的是成员变量同时是通过对象方法来对成员变量进行封装的。那么这里就可以引出我们的set方法和get方法。
1、set方法
1)作用:用来设置成员变量,可以再方法中过滤掉一些不合理的值
2)命名规范:
- 方法都是以set开头,而且后面跟上成员变量名,成员变量的首字母必须大写
- 形参名称不要跟成员变量同名
2、get方法
1)作用:返回对象内部的成员变量
2)命名规范:get方法的方法名一般就跟成员变量同名
3、成员变量的命名规范
- 成员变量都以下划线"_"开头
- 可以跟get方法的方法名区分开来
- 可以跟其他局部变量区分开来,一看到"_"开头的变量就知道是成员变量
4、代码示例:
#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
5、封装的好处
- 过滤掉不合理的赋值
- 屏蔽内部赋值过程
- 让外界不必关注内部的细节
二、继承
继承是用来表示类与类之间的关系的,如果我们说类B继承了类A,那么类B和类A之间到底有什么联系呢?
1、继承的特点
- 子类可以访问父类的成员变量和方法(对象方法\类方法)
- 子类和父类不能拥有相同的成员变量
- 子类可以重写父类的方法
- 单继承
2、继承的好处
- 不改变原来模型的基础上拓充了方法
- 抽取了公共代码
- 建立了类与类之间的关系
3、继承的坏处
- 耦合性强
4、继承的语法,以及代码示例
类A:类B 即表示B继承了A,如下所示:
// Animal的声明
@interface Animal : NSObject
{
int _weight;
}
- (void)eat;
@end
// Animal的定义
@implementation Animal
- (void)eat {
NSLog(@"吃吃吃-体重:%d", _weight);
}
@end
子类在父类的基础上拓充属性和方法
// Bird的声明
@interface Bird : Animal
{
int _height;
}
- (void)fly;
@end
// Bird的定义
@implementation Bird
- (void)fly {
NSLog(@"飞飞飞-高度:%d", _height);
}
@end
// Dog的声明
@interface Dog : Animal
{
int _speed;
}
- (void)run;
@end
// Dog的定义
@implementation Dog
- (void)run {
NSLog(@"跑跑跑-高度:%d", _speed);
}
@end
三、多态
1、多态的基本概念
- 某一类事物的多种形态
- OC对象具有多态性
2、多态的体现
- 父类指针指向子类对象
- 父类指针访问对应的属性和方法
Person *p = [Student new];
p->age = 100;
[p walk];
补充完整就是:
#import <Foundation/Foundation.h>
//======Person=========//
@interface Person : NSObject
{
int _age;
}
// age 的set方法和get方法
- (void)setAge: (int)age;
- (int)age;
- (void)walk;
@end
@implementation Person
// age 的set方法和get方法
- (void)setAge: (int)age
{
_age = age;
if (age < 20)
_age = 0;
}
- (int)age
{
return _age;
}
- (void)walk
{
NSLog(@"%d岁的Person----walk", _age);
}
@end
//=========Student========//
@interface Student : Person
@end
@implementation Student
// walk方法重写
- (void)walk
{
NSLog(@"%d岁的Student-----walk", _age);
}
@end
int main(int argc, const char * argv[]) {
// 父类指针指向子类对象
Person *p = [Student new];
[p setAge: 10];
[p walk]; // 输出结果为:11岁的Student------walk
return 0;
}
3、多态的好处
- 如果参数中用的是父类类型,可以传入父类、子类对象,从而节省代码
- 代码体现如下:
// ....
// feed 函数,功能喂
void feed(Animal *aa)
{
[aa eat];
}
// ....
4、多态的局限性
- 不能访问子类特有的属性和方法(可以通过强制类型转换)
// ....
Animal *aa = [Dog new];
// Dog中有个新run方法
[aa run] ×
// 强制转换 aa 为Dog类型
Dog *dd = (Dog *)aa;
[dd run];
// .....