OC第六节—— 继承与类别
1、继承: 父类和子类的关系。
1.1 生活中的继承
父类 子类 父类 子类 对象
人 男人 男人 老男人 ***
外星人 变形精钢 变形精钢 汽车人 大黄蜂、擎天柱
生物 动物 动物 猫 多啦A梦
人
男人 女人
老男人 小女人
外星人
变形精钢 火星人
汽车人
【名词】
父类 parenClass 超类 superClass 基类
子类 childClass 子类 subClass 派生类
【注】
把继承又叫做派生
父类的属性(成员变量)和方法,子类可以直接获取,这个过程就叫做继承
子类在父类的基础上,创建了自己独有的成员变量和方法,这个过程就叫做
派生。
继承和派生其实是说的继承概念的不同的侧重点。
1.2 代码中的继承
<1>继承的基本语法
a.
@interface 子类名:父类名
@end
b.继承之后
子类可以使用父类的所有方法
子类可以获得父类非私有的成员变量
<2>重写
1.子类从父类继承的方法, 有时候不适合子类,子类可以重写这个方法
2.重写就是重新实现一遍父类的方法(方法名一样 实现内容不同)
3.子类重写父类方法之后,子类对象最终执行的是子类重写之后的方法
1.3 继承在内存中的体现
子类继承父类之后 子类对象的构成:
1) 父类的字段和方法
2) 子类自己独有的字段和方法
画图画出子类对象的构成
【继承的作用】
1、快速创建多个形似的类
2、对类进行扩展
3、自定义一些系统的一些功能控件
myButton : UIButton
//父类 #import <Foundation/Foundation.h> @interface Car : NSObject { NSString *_brand; NSString *_color; } //@property 生成的是私有的成员变量 @property (nonatomic, copy) NSString *brand; @property (nonatomic, copy) NSString *color; //- (void)setBrand:(NSString *)brand; //- (void)setColor:(NSString *)color; // //- (NSString *)brand; //- (NSString *)color; @end #import "Car.h" @implementation Car //@synthesize brand = _brand; //- (void)setBrand:(NSString *)brand //{ // _brand = brand; //} //- (void)setColor:(NSString *)color //{ // _color = color; //} // //- (NSString *)brand //{ // return _brand; //} //- (NSString *)color //{ // return _color; // //}
//子类 #import "Car.h" @interface Trunk : Car { NSInteger _weight; } - (void)setWeight:(NSInteger)weight; - (NSInteger)weight; - (NSString *)description; @end #import "Trunk.h" @implementation Trunk - (void)setWeight:(NSInteger)weight { _weight = weight; } - (NSInteger)weight { return _weight; } - (NSString *)description { return [NSString stringWithFormat:@"brand: %@, color: %@, weight: %ld", _brand, _color, _weight]; } @end
//子类 #import "Car.h" //继承父类Car的_brand 和 _color 字段 //继承了父类的 //- (void)setBrand:(NSString *)brand; //- (void)setColor:(NSString *)color; // //- (NSString *)brand; //- (NSString *)color; @interface Taxi : Car { NSString *_company; } - (void)setCompany:(NSString *)company; - (NSString *)company; - (NSString *)description; @end #import "Taxi.h" @implementation Taxi - (void)setCompany:(NSString *)company { _company = company; } - (NSString *)company { return _company; } - (NSString *)description { return [NSString stringWithFormat:@"brand: %@, color: %@, company: %@", _brand,_color,_company]; } @end
//主函数 #import <Foundation/Foundation.h> #import "Taxi.h" #import "Trunk.h" int main(int argc, const char * argv[]) { @autoreleasepool { Taxi *taxi = [[Taxi alloc] init]; [taxi setBrand:@"大众"]; [taxi setCompany:@"中南"]; [taxi setColor:@"绿色"]; NSLog(@"taxi: %@", taxi); Trunk *trunk = [[Trunk alloc] init]; [trunk setBrand:@"东风"]; [trunk setColor:@"黄色"]; [trunk setWeight:10000]; NSLog(@"trunk: %@", trunk); } return 0; }
———————————————————
2、多态与类的消息机制 (多态—多种状态)
【多态】重载(OC没有)、重写、虚函数
//其实多态就是指,同一个接口不同的实现
OC里面的方法,叫做虚方法
【虚方法】
1.响应消息,不看指针,看对象。
2.父类的指针,可以指向子类的对象。
【注】
虚方法体现了不同事物被同一事件触发,有不同的响应。
给不同对象发送相同的消息,反应不一样。
1、父类的指针指向子类的对象
2、多态的应用。
幼儿园—
老师ask:boy , boy 回答“不是我”; tell
老师ask: girl girl 回答“就是他” tell
继承关系:
Kid 小孩类作为 -父类 tell方法
boy 继承于kid 重写 tell — “不是我”
girl 继承于KId 重写tell — “就是他”
Teacher
//老师 #import <Foundation/Foundation.h> #import "Kid.h" @interface Teacher : NSObject - (void)askKid:(Kid *)kid; @end #import "Teacher.h" @implementation Teacher - (void)askKid:(Kid *)kid { NSLog(@"老师问: %@", [kid class]); [kid tell]; } @end //孩子 #import <Foundation/Foundation.h> @interface Kid : NSObject - (void)tell; @end #import "Kid.h" @implementation Kid - (void)tell { return; } @end //男孩 #import "Kid.h" @interface Boy : Kid @end #import "Boy.h" @implementation Boy - (void)tell { NSLog(@"不是我!"); } @end //女孩 #import "Kid.h" @interface Girl : Kid @end #import "Girl.h" @implementation Girl - (void)tell { NSLog(@"就是他!"); } @end //主函数 #import <Foundation/Foundation.h> #import "Teacher.h" #import "Boy.h" #import "Girl.h" int main(int argc, const char * argv[]) { @autoreleasepool { Teacher *laowang = [[Teacher alloc] init]; Boy *boy = [[Boy alloc] init]; Girl *girl = [[Girl alloc] init]; [laowang askKid:boy]; [laowang askKid:girl]; } return 0; }
3、打豆豆—打不同的动物,不同的响应
Animal 父类
- (void)beaten;
Cat —
Tiger
Duck
Person
- (void)beatAnimal:(Animal *)animal
{
[animal beaten];
}
———————————————————
5、类别/类目 category
思考:如何给NSString 添加一个逆序的方法。
<1>类别的基本语法
@interface 类名 (类别名)
例如:给字符串添加扩充一个逆序的方法
@interface NSString (Reverse) //()扩充的类别的名字
//不能够扩充成员变量,只能够扩充方法
- (NSString *)reverseString;
@end
@implementation NSString (Reverse)
//逆序
- (NSString *)reverseString
{
NSMutableString *string = [[NSMutableString alloc] init];
for (NSInteger i = [self length] - 1; i >= 0; i --) {
unichar C = [self characterAtIndex:i];
[string appendFormat:@"%C", C];
}
return string;
}
//输出字符串
- (void)putString
{
NSLog(@"%@", self);
}
@end
//需要在使用类别方法的文件里面倒入类别的头文件
#import "NSString+Reverse.h"
注:一旦使用类别给已有的类增补方法,那么这个类的对象就可以使用这个方法
<2>.类别功能:
1. 可以给已有/ 系统原生的类增补方法
2.可以对类的方法进行分类管理,可以将类的实现分散到多个不同文件或多个不同框架中。
<3>使用类别需要注意的问题
1.类别中不能添加成员变量
2.使用类别增补的方法须导入类别头文件
3.父类类别中的方法,子类也可以用
<4>类扩展/匿名类别
当不想对外公开一些类的方法时,我们可以使用类扩展
1.类扩展的基本语法
在.m文件中
@interface Person()//没有名字
- (void)song;
@end
@implementation Person
- (void)song{
NSLog(@"我心永恒");
}
@end
注: 类扩展中的声明和实现都放在.m文件中
2.类扩展的功能
1.可以实现私有方法
2.方便程序员调用不公开的方法
3.可以声明成员变量