OC语言 - 面向对象:继承

■ 继承

OC 不允许子类和父类拥有相同名称的成员变量名,但子类可以拥有和父类相同名称的方法

OC 属于单根继承,不可以互相继承,它只能有一个父类!OC 中的根类只有一个 NSObject

继承具有传递性,子类会拥有父类除了私有实例变量以外的所有特征和行为,如果子类从父类中继承的方法不满意,可以重写该方法,但是这样会覆盖父类中的实现

继承的优缺点

1. 好处:简化代码,抽取出重复代码;建立了类和类之间的联系,保证类的完整性

2. 坏处:耦合性太强

如图所示:Person 继承了 NSObject;Student 继承了 Person

当我们在代码中书写 Student *s = [[Student alloc] init] 时,编译器就会把 Student 和它的父类全部加载进内存!个类对象中都有一个 Superclass 指针,指向该类的父类;同样地,每个对象中有一个 isa 指针,指向该对象所属的类!注:根元类的 isa 指向自身,而它的 superClass 指向根类 


■ 如何使用

代码示例:下面代码中的继承关系如是 CollegeStudent -> Student -> Person

// - Person.h

 1 #import <Foundation/Foundation.h>
 2 @interface Person : NSObject{
 3     NSString *_name;
 4     NSString *_sex;
 5     NSInteger _age;
 6 }
 7 
 8 - (void)sayHI;
 9 
10 - (void)setName:(NSString *)name;
11 - (NSString *)name;
12 
13 - (void)setSex:(NSString *)sex;
14 - (NSString *)sex;
15 
16 - (void)setAge:(NSInteger)age;
17 - (NSInteger)age;
18 
19 - (id)initWithName:(NSString *)name;
20 - (id)initWithName:(NSString *)name
21                sex:(NSString *)sex;
22 - (id)initWithName:(NSString *)name
23                sex:(NSString *)sex
24                age:(NSInteger)age;
25 
26 + (id)personWithName:(NSString *)name;
27 + (id)personWithName:(NSString *)name sex:(NSString *)sex;
28 
29 @end

// - Person.m

 1 #import "Person.h"
 2 @implementation Person
 3 // 重写父类方法
 4 - (id)init{
 5     self = [super init];
 6     
 7     if (self) {
 8         _name = @"Hazell";
 9         _sex = @"female";
10         _age = 26;
11     }
12     return self;
13 }
14 
15 - (void)sayHI{
16     NSLog(@"name : %@,sex : %@ ,age : %ld",_name,_sex,_age);
17 }
18 
19 - (void)setName:(NSString *)name{
20     _name = name;
21 }
22 
23 - (NSString *)name{
24     return _name;
25 }
26 
27 - (void)setSex:(NSString *)sex{
28     _sex = sex;
29 }
30 
31 - (NSString *)sex{
32     return _sex;
33 }
34 
35 - (void)setAge:(NSInteger)age{
36     _age = age;
37 }
38 
39 - (NSInteger)age{
40     return _age;
41 }
42 
43 - (id)initWithName:(NSString *)name{
44     return [self initWithName:name sex:nil age:0];
45 }
46 
47 - (id)initWithName:(NSString *)name
48                sex:(NSString *)sex{
49     return [self initWithName:name sex:sex age:0];
50 }
51 
52 - (id)initWithName:(NSString *)name
53                sex:(NSString *)sex
54                age:(NSInteger)age{
55     self = [super init];
56     if (self) {
57         _name = name;
58         _sex = sex;
59         _age = age;
60     }
61     return self;
62 }
63 
64 // 便利构造器:实质上就是把初始化方法再做一层封装,是 + 方法
65 + (id)personWithName:(NSString *)name{
66 
67     Person *p =[[Person alloc] initWithName:name];
68     return p; 
69 }
70 
71 + (id)personWithName:(NSString *)name sex:(NSString *)sex{
72 
73     Person *per = [[Person alloc] initWithName:name sex:sex];
74     return per;
75 }
76 
77 @end

// - Student.h

 1 #import "Person.h"
 2 @interface Student : Person{
 3     NSInteger _number;
 4     CGFloat   _score;
 5 }
 6 
 7 - (void)setNumber:(NSInteger)number;
 8 - (NSInteger)number;
 9 
10 - (void)setScore:(CGFloat)score;
11 - (CGFloat)score;
12 
13 - (id)initWithName:(NSString *)name
14              score:(CGFloat)score;
15 - (id)initWithName:(NSString *)name
16                sex:(NSString *)sex
17              score:(CGFloat)score;
18 - (id)initWithName:(NSString *)name
19                sex:(NSString *)sex
20                age:(NSInteger)age
21             number:(NSInteger)number
22              score:(CGFloat)score;
23 
24 @end

// - Student.m

 1 #import "Student.h"
 2 @implementation Student
 3 
 4 - (id)init{
 5     self = [super init];
 6     if (self) {
 7         _number = 2010341130;
 8         _score = 99.9;
 9     }
10     return self;
11 }
12 
13 - (void)sayHI{
14     NSLog(@"I am a student name : %@,sex : %@,age : %ld,number : %ld,score : %.1f",_name,_sex,_age,_number,_score);
15 }
16 
17 - (void)setNumber:(NSInteger)number{
18     _number = number;
19 }
20 
21 - (NSInteger)number{
22     return _number;
23 }
24 
25 - (void)setScore:(CGFloat)score{
26     _score = score;
27 }
28 
29 - (CGFloat)score{
30     return _score;
31 }
32 
33 - (id)initWithName:(NSString *)name
34              score:(CGFloat)score{
35     return [self initWithName:name sex:nil age:0 number:0 score:score];
36 }
37 
38 - (id)initWithName:(NSString *)name
39                sex:(NSString *)sex
40              score:(CGFloat)score{
41     return [self initWithName:name sex:sex age:0 number:0 score:score];
42 }
43 
44 - (id)initWithName:(NSString *)name
45                sex:(NSString *)sex
46                age:(NSInteger)age
47             number:(NSInteger)number
48              score:(CGFloat)score{
49     self = [super initWithName:name sex:sex age:age];
50     if (self) {
51         _number = number;
52         _score = score;
53     }
54     return self;
55 }
56 
57 @end

// - CollegeStudent.h

 1 #import "Student.h"
 2 @interface CollegeStudent : Student{
 3     NSString *_major;
 4     NSString *_academy;
 5 }
 6 
 7 - (void)setMajor:(NSString *)major;
 8 - (NSString *)major;
 9 
10 - (void)setAcademy:(NSString *)academy;
11 - (NSString *)academy;
12 
13 - (id)initWithName:(NSString *)name
14                sex:(NSString *)sex
15                age:(NSInteger)age
16             number:(NSInteger)number
17              score:(CGFloat)score
18              major:(NSString *)major
19            academy:(NSString *)academy;
20 - (id)initWithName:(NSString *)name
21                sex:(NSString *)sex
22              major:(NSString *)major
23            academy:(NSString *)academy;
24 - (id)initWithName:(NSString *)name
25                sex:(NSString *)sex
26             number:(NSInteger)number
27              score:(CGFloat)score
28            academy:(NSString *)academy;
29 
30 @end

// - CollegeStudent.m

 1 #import "CollegeStudent.h"
 2 @implementation CollegeStudent
 3 
 4 // 当从父类继承来的方法不能满足子类需求的时候,就需要重写父类方法
 5 // 对象的初始化过程:首先要一级级地调用到继承树的最顶端,然后再从上往下一级级地返回对象!如果中间有一级初始化失败,那么下一层将不再初始化且返回空对象
 6 - (id)init{
 7     self = [super init];
 8     if (self) {
 9         _major = @"计算机科学与技术";
10         _academy = @"研究所";
11     }
12     return self;
13 }
14 
15 - (void)sayHI{
16     NSLog(@"I am a college student , name : %@,sex : %@,age : %ld,number : %ld,score : %.1f,major : %@,academy : %@",_name,_sex,_age,_number,_score,_major,_academy);
17 }
18 
19 - (void)setMajor:(NSString *)major{
20     _major = major;
21 }
22 
23 - (NSString *)major{
24     return _major;
25 }
26 
27 - (void)setAcademy:(NSString *)academy{
28     _academy = academy;
29 }
30 
31 - (NSString *)academy{
32     return _academy;
33 }
34 
35 - (id)initWithName:(NSString *)name
36                sex:(NSString *)sex
37                age:(NSInteger)age
38             number:(NSInteger)number
39              score:(CGFloat)score
40              major:(NSString *)major
41            academy:(NSString *)academy{
42     self = [super initWithName:name sex:sex age:age number:number score:score];
43     if (self) {
44         _major = major;
45         _academy = academy;
46     }
47     return self;
48 }
49 
50 - (id)initWithName:(NSString *)name
51                sex:(NSString *)sex
52              major:(NSString *)major
53            academy:(NSString *)academy{
54     return [self initWithName:name sex:sex age:0 number:0 score:0 major:major academy:academy];
55 }
56 
57 - (id)initWithName:(NSString *)name
58                sex:(NSString *)sex
59             number:(NSInteger)number
60              score:(CGFloat)score
61            academy:(NSString *)academy{
62     return [self initWithName:name sex:sex age:0 number:number score:score major:nil academy:academy];
63 }
64 
65 @end

// - main.m

 1 #import <Foundation/Foundation.h>
 2 #import "Person.h"
 3 #import "Student.h"
 4 #import "CollegeStudent.h"
 5 int main(int argc, const char * argv[]) {
 6     @autoreleasepool {
 7         
 8         Person *person = [[Person alloc] init];
 9         [person sayHI];
10         Person *person01 = [Person personWithName:@"Jane"];// 使用便利构造器
11         [person01 sayHI];
12         [person setName:@"Joson"];
13         [person sayHI];
14         NSLog(@"%ld",[person age]);
15         
16         Student *student = [[Student alloc] init];
17         [student sayHI];// 输出 name sex age 是有值的,因为 Student 初始化方法中调用了父类的初始化方法
18         
19         // 父类赋值方法
20         [student setName:@"Jane"];
21         [student setSex:@"female"];
22         [student setAge:19];
23         
24         // 自身赋值方法
25         [student setNumber:2010341110];
26         [student setScore:26];
27         [student sayHI];
28         
29         CollegeStudent *collegestudent = [[CollegeStudent alloc] init];
30         [collegestudent setName:@"Kardashian"];
31         [collegestudent setAge:21];
32         [collegestudent setSex:@"female"];
33         [collegestudent setNumber:20153622];
34         [collegestudent setScore:6.9];
35         [collegestudent setMajor:@"艺术"];
36         [collegestudent setAcademy:@"花花学院"];
37         [collegestudent sayHI];
38     }
39     return 0;
40 }

 

posted on 2018-08-06 17:39  低头捡石頭  阅读(54)  评论(0编辑  收藏  举报

导航