Objective-C基础学习笔记(四)-面向对象的三大特性之继承-self关键字

一. 概述

OC语言支持面向对象那么也就有面向对象编程 (OOP) 语言的一个主要功能就是--继承。那么何为继承呢?我对继承的理解是:继承是指这样一种功能:它可以使用它父类的所有功能包括成员变量和方法,并在无需重新编写原来的类的情况下对这些功能进行扩展。通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“父类”或“超类”。

二 . 继承

继承的好处:
       1)不改变原来模型的基础上,拓充方法
       2)建立了类与类之间的联系
       3)抽取了重复的代码

继承的坏处:
       耦合性强,子类严重依赖父类。

继承的细节:
    1)单继承:一个类只能有一个父类,不能有多个。
    2)子类和父类不能有相同的成员变量。
    3)方法的重写:子类重新实现父类中的某个方法,覆盖父类以前父类的方法,具体看下文示例.

    4)关于继承关系中方法的调用处理:调用某个对象的方法时优先在子类中找,找不到才去父类中找,在到爷爷类中找。

继承的使用场合:

    一个类的所有属性都是你想要的,一般就继承,如果它的部分属性是你想要的,可以从这个类中抽取出另一个父类,但有一点要注意,两个类之间的关系应该是“属于”关系。例如,老师是一个人,学生也是一个人,因此这两个类都可以继承 Person 类。但是 Car类却不能继承 Person类,继承的关系时严格的属于关系,也可以表达成 “子类是父类”如学生是人,但说成汽车是人就不符合逻辑了。

组合关系:

    上文说到继承关系应该是子类属于父类,但有一种情况是,一个类拥有另一个类的成员变量,如Score类中包含:数学成绩、语文成绩,但Student类也包含数学成绩和语文成绩,这时不能用Student类继承成绩类因为不能说成学生是成绩,那么这种关系怎么表达呢,那就是组合关系,表达成一个类拥有另一个类,如学生拥有成绩。

简单总结如下:

  组合:xxx拥有xxx  例:学生拥有成绩

 继承:xx xxx    例:学生是人狗是动物

 组合关系使用示例:

 /* 成绩类的声明 */
@interface Score :NSObject
 {
    int mathScore; // 数学成绩
    int cScoer;    // C语言成继
 }
/* 成绩类的实现 */
 @implementation Score
 @end
 /* 学生类的声明 */
 @interface Student
 { 
    // 学生类也要包含两个成绩时,即可使用组合能使用继承
    //int mathScore;
    //int cScoer;
    Score *_score;
    int num;
 }
 @end
 /* 学生类的实现 */
 @implementation Score
 @end

 三 .  继承使用示例

 

 1 /* Person类的声明 */
 2 @interface Person : NSObject
 3 {
 4     int _age; // 年龄属性
 5 }
 6 - (void)setAge:(int)age;
 7 - (int)age;
 8 // 跑方法
 9 - (void)run;
10 @end
11 
12 /* Person 类实现 */
13 @implementation Person
14 - (void)setAge:(int)age
15 {
16     _age = age;
17 }
18 - (int)age
19 {
20     return _age;
21 }
22 
23 - (void)run
24 {
25     NSLog(@"Person run!!");
26 }
27 @end
28 
29  

 

下面是学生类从Person类继承并重写了run方法

 1  
 2 
 3 /* 学生类继承人类 */
 4 // : Person 继承了Person里面所有的成员变量和方法
 5 @interface Student : Person
 6 {
 7     //子类和父类不能有相同的成员变量
 8     // int _age;
 9     int num;  //在父类基础上的扩充学号属性
10 }
11 @end
12 
13 @implementation Student
14 /* 重写:子类重新实现父类中的某个方法,覆盖父类以前父类的方法 */
15 - (void)run
16 {
17     NSLog(@"Student run!!");
18 }
19 @end</span><span style="font-size:14px;">
20 </span>
21 
22 测试代码:
23 
24  
25 
26  
27 
28 int main()
29 {
30    /* 
31     Dog *d = [Dog new];
32     [d setAge:5];
33     NSLog(@"age = %d",[d age]);
34     Cat *c = [Cat new];
35     [c setAge:3];
36     NSLog(@"age = %d",[d age]);
37     */
38     
39     Student *s = [Student new];
40     [s setAge:15];
41     NSLog(@"age = %d",[s age]);
42     [s run];
43     //优先在自己的实现中找方法找不到才去父类中找
44     return 0;
45 }

 

运行结果:

 

nikodeimac:inherit niko$ ./a.out 

2015-03-17 22:22:07.397 a.out[3368:256407] age = 15

2015-03-17 22:22:07.398 a.out[3368:256407] Student run!!

四.  self关键字

概念:谁调用了当前方法,self就指向谁;
1.self出现在对象方法中,self就代表对象
2.self出现在类方法中,self就代表类
使用相关:
1.self出现的地方:可在所有OC的方法中,就是不能在函数中;
使用方式:

1.使用 "self->成员变量名"访问当前方法调用的成员变量

2.使用 "[self 方法名];"来调用方法(对象方法\类方法)

self 使用注意

1. 引发死循环:

 1 @implementation Dog
 2 
 3 - (void)test
 4 {
 5     //引发死循环
 6     [self test]
 7 }
 8 
 9 + (void)test1
10 {
11     //引发死循环
12     [self test]
13 }
14 @end
2.用self去调用函数
self关键字使用示例1调用对象方法 :
 1 /* Dog类的声明 */
 2 @interface Dog : NSObject
 3 - (void)bark; // 叫 方法
 4 - (void)run;  // 跑 方法
 5 @end
 6 
 7 @implementation Dog
 8 /* 叫方法实现 */
 9 - (void)bark
10 {
11     NSLog(@"汪 汪 汪");
12 }
13 //跑方法实现 需求:跑之前先叫两次
14 - (void)run
15 {
16     /* self在对象方法中,这个方法只能由对象调用所以self指向当前对象 */
17     [self bark]; // 调用自己的叫方法两次
18     [self bark];
19     NSLog(@"跑 跑 跑");
20 }
21 @end
22 测试代码:
23 int main()
24 {
25     Dog *d = [Dog new];
26     /* 调用run方法的是对象 */
27     [d run];
28     return 0;
29 }

 

运行结果:

nikodeimac:self niko$ ./a.out 

2015-03-17 22:44:20.634 a.out[3402:262954] 汪 汪 汪

2015-03-17 22:44:20.635 a.out[3402:262954] 汪 汪 汪

2015-03-17 22:44:20.635 a.out[3402:262954] 跑 跑 跑





 

 



posted @ 2015-03-17 21:11  HugoJiang  阅读(154)  评论(0编辑  收藏  举报