三大特性:封装、继承和多态
一、封装
1、set方法和get方法
@public类型的成员可以被随意访问,应该使用set方法和get方法来管理成员的访问,这样做可以达到过滤不合理的值;屏蔽内部的赋值过程;让外界不必关注内部的细节等好处
2、set方法
- 用来设置成员变量,可以在方法里面过滤掉一些不合理的值
- 方法名都是以set开头,而且后面跟上成员变量名,成员变量名的首字母必须大写
- 形参名称不要跟成员变量同名
3、get方法
- 作用:返回对象内部的成员变量
- 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)
{
<span style="white-space:pre"> </span>wheels = 1;
}
_wheels = wheels;
}
// get方法的实现
- (int) wheels
{
return _wheels;
}
@end
二、继承
1、继承的基本用法
类名:Dog
属性:年龄(_age)
方法:run
类名:Cat
属性:年龄(_age)
方法:run
现在有两个类Dog、Cat,有相同的属性age和方法run,可以抽出一个父类Animal拥有共同的属性和方法,代码如下:
#import <Foundation/Foundation.h>
/**********Animal的声明******************/
@interface Animal : NSObject
{
int _age;
}
- (void)setAge:(int)age;
- (int)age;
- (void)run;
@end
/**********Animal的实现******************/
@implementation Animal
- (void)setAge:(int)age
{
_age = age;
}
- (int)age
{
return _age;
}
- (void)run
{
NSLog(@"跑起来……");
}
@end
/**********Dog的声明和实现******************/
@interface Dog : Animal
@end
@implementation Dog
@end
/**********Cat的声明和实现******************/
@interface Cat : Animal
@end
@implementation Cat
@end
继承结构如下
这样可以抽取两个类中的重复代码,建立类之间的关系
注意:
- :Animal表示继承了Animal ,相当于拥有了Animal 里面的所有成员变量和方法
- Animal 称为Dog的父类,Dog称为Animal 的子类
- 父类(又叫超类) superclass 子类 subclass/subclasses
- 子类可以拥有父类中的所有成员变量和方法
- 基本上所有类的根类是NSObject
2、子类在父类的基础上拓充属性和方法
@interface Dog : Animal
{
@public
int _weight;
}
- (void)eat;
@end
@implementation Dog
- (void)eat
{
NSLog(@"%d岁的动物吃起来……",_age);
}
@end
子类Dog新建了成员变量weight和方法eat,同时拥有父类Animal的成员变量和方法
注意:
- 父类必须声明在子类的前面
- 不允许子类和父类拥有相同名称的成员变量,例如不能再Dog中再定义int _age;
- 子类可以重写父类中的方法,覆盖父类以前的行为
- 调用某个对象的方法时,优先在当前对象找,如果找不到再到父类在找
- 单继承
- 继承耦合性太强
3、使用场合
1) 当两个类拥有相同属性和方法的时候,就可以将相同的东西抽取到一个父类中
2) 当A类拥有B类中的部分属性和方法时,可以考虑让B类继承A类
4、super
- 直接调用父类中的某个方法
- super处在对象方法中,就调用父类的对象方法
- super处在类方法中,就调用父类的类方法
三、多态
1、基本概念
OC对象具有多态性,多态可以理解为多种形态,而且多态是在继承的基础上才产生的,可以说是没有继承就没有多态。
2、代码体现
以继承中的类为例子
创建Dog类型的对象一般为
Dog *d = [Dog new];
利用多态为
Animal *a = [Dog new];
[a run];
- 父类指针指向了子类对象
- 父类指针可以访问对应的属性和方法
3、多态的好处
如果函数、方法参数中使用的是父类类型,可以传入父类子类对象
示例:
Dog *d = [Dog new];
Cat *c = [Cat new];
void pao(Animal *a)
{
[a run];
}
pao(d);
pao(c);
4、多态的局限性
父类类型的变量不能直接调用子类特有的方法,必须强制转换为子类类型的变量后,才能直接调用子类特有的方法。
示例:
Animal *aa = [Dog new];
[aa run]; // 不能直接调用
// 强制转换
Dog *dd= (Dog *) aa;
[dd run];