------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
面向对象设计的三大特性:封装、继承、多态
1、封装的概念及原理:
将数据隐藏起来,向外界提供展示以及接口,只有使用此类的方法函数才可以访问或者设置数据,不可被外部任意存储是面向对象设计的本质。降低了数据被无用的可能性!
在OC中,使用@interface 和@implementation来处理类。
2、封装的原理
实例变量默认只能被当前的对象访问
3、封装的好处
更加接近人类的思考方式
只需要关注对象,不需要关注步骤
比如下面这个例子:
<span style="font-size:12px;">#import <Foundation/Foundation.h>
@interface Gun : NSObject
{
@public
int _bullet;//子弹的个数
}
-(void)fire;
-(void)setBullet:(int)bullet;
@end
@implementation Gun
-(void)fire{
if (_bullet>0){
_bullet--;
NSLog(@"机枪正在扫射,剩余%d颗子弹",_bullet);
}else {
NSLog(@"没子弹了,请装弹!");
}
}
-(void)setBullet:(int)bullet{
if (bullet>0) {
_bullet = bullet;
}else{
_bullet =0;
}
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Gun *gun= [Gun new];
//使用set方法设置Gun类的对象bullet的值为5
[gun setBullet:5];
[gun fire];
[gun fire];
[gun fire];
[gun fire];
[gun fire];
}
return 0;
}
</span>
4、封装的实现步骤
set 方法(设置器)
作用:为外界提供一个设置成员变量值的方法
命名规范:
1)必须以set开头
2)set后面跟成员变量的名称,首字母大写
3)返回值一定是一个 void
4)一定要接受一个参数,而且参数的类型要和成员变量的类型一致
5)形参名不能和成员变量名一样
6)set方法一定是一个对象方法
set方法的好处
1)不让数据暴露在外面,保证了数据的安全性
2)对设置的数据进行过滤
get 方法
作用:
返回对象内部的成员变量
命名规范:
1)是一个对象方法
2)一定有返回值,返回值的类型和成员变量的类型要一致
3)方法名是去掉下划线的成员变量名
4)一定没有参数
5)get方法的实现中,一定是返回成员变量值
6)形参名不能和成员变量名同名
代码示例:
<span style="font-size:12px;">#import <Foundation/Foundation.h>
@interface Car : NSObject
{
@public
//声明
NSString *_logo;//什么牌子的车
int _speed; //车的速度
}
- (void)run;
//set方法
-(void)setSpeed : (int)speed;
//get方法
- (int)speed;
@end
@implementation Car
- (void)run
{
if (_speed>0)
{
NSLog(@"%@以%d的速度在狂飙",_logo,_speed);
}
}
-(void)setSpeed : (int)speed{
//set方法的实现
if (speed<0)
{
speed = 0;
}
_speed = speed;
}
//get方法的实现
- (int)speed
{
return _speed;
}
@end
</span>
5、类的继承
概念
子类获得父类的特性的概念就是继承
继承的注意事项:
1)父类被继承了,还是可以照常使用
2)子类不能定义和父类同名的变量,但是可以继承父类的变量
3)OC支持单一继承,不支持多继承
4)OC支持多层继承
继承的好处
1)不改变原来模型的基础上,拓充方法
2)建立了类与类之间的联系
3)抽取了公共代码
坏处:耦合性强
继承的用法 和代码实现:
<span style="font-size:12px;">//Animal的声明
@interface Animal : NSObject
{
@public
int _age;
int _speed;
}
-(void)eat:(NSString *)food;
-(void)run;
@end</span>
<span style="font-size:12px;">#import "Animal.h"
@implementation Animal
//Animal的实现
-(void)eat:(NSString *)food{
NSLog(@"吃%@",food);
}
-(void)run{
NSLog(@"以%d速度跑",_speed);
}
@end
</span>
<span style="font-size:12px;">#import "Animal.h"
//Dog的声明
@interface Dog : Animal
- (void)lookAfterHome;
@end
</span>
<span style="font-size:12px;">#import "Dog.h"
//Dog的实现
@implementation Dog
- (void)lookAfterHome{
NSLog(@"Dog看家");
}
@end</span>
<span style="font-size:12px;">#import "ArmyDog.h"
//ArmyDog的声明
@implementation ArmyDog
-(void)search
{
NSLog(@"ArmyDog搜救");
}
@end
</span>
<span style="font-size:12px;">#import "ArmyDog.h"
//ArmyDog的实现
@implementation ArmyDog
-(void)search
{
NSLog(@"ArmyDog搜救");
}
@end
</span>
<span style="font-size:12px;">#import <Foundation/Foundation.h>
#import "Animal.h"
#import "Dog.h"
#import "ArmyDog.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Animal *animal = [Animal new];
animal ->_age = 1;
animal ->_speed = 50;
[animal eat:@"红烧肉"];
[animal run];
Dog *dog = [Dog new];
dog ->_speed = 100;
[dog eat:@"骨头"];
[dog run];
[dog lookAfterHome];
ArmyDog *armyDog = [ArmyDog new ];
armyDog ->_speed = 200;
[armyDog eat:@"牛肉"];
[armyDog run];
[armyDog search];
}
return 0;
}</span>
这里的Animal 是Dog的基类,而Dog又是ArmyDog的基类,他们都可以继承Animal的属性
子类方法和属性的访问过程: 如果子类没有,就去访问父类的
6、多态的概念和条件
1.什么是多态
1)多态就是某一类事物的多种形态。
2)程序中的多态: 不同的对象以自己的方式响应相同名称方法的能力称为多态。
2.多态的条件
1)有继承关系、有方法重写(子类把父类的同名方法给重写了)
2)父类的声明变量指向子类对象
代码实现:用父类类型的指针指向了子类对象,这就是多态
<span style="font-size:12px;"> Animal *animal = [Animal new];
//实例化狗的对象
Animal *animal1= [Dog new];
[animal1 run];
//实例化猫的对象
Animal *animal2= [Cat new];
[animal2 run];</span>
3.多态的优点
多态的主要的好处就是简化了编程接口。节省代码,使代码的扩展性和复用性更好一些。
4.多态的局限性
不能访问子类的属性,但是可以考虑强制转换。
5、多态的注意点
1)如果存在多态,父类可以访问子类特有的方法
<span style="font-size:12px;">
[dog bark];
Animal *animal1= [Dog new];
[(Dog*)animal1 bark];//把父类的指针,强制转换
</span>
2)如果不存在多态,父类是不可以访问子类特有的方法<span style="font-size:12px;">
[dog bark];
Animal *animal2= [Animal new];
[(Dog*)animal2 bark];//这是错误的,不能强制转换</span>