一、封装

1.什么是封装

在程序上,隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别;将对象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成“类”,其中数据和函数都是类的成员。

 1> set方法

  ① 作用:提供一个方法给外界设置成员变量值,实现对参数的相应过滤

  ② 命名规范

   *方法名必须以set开头

   *set后面跟上成员变量的名称,成员变量名首字母必须大写

   *返回值一定是void

   *一定要接收一个参数,而且参数类型跟成员变量类型一致

   *形参的名称不能跟成员变量名一样

 1 #import <Foundation.foundation.h>
 2 
 3 @interface Student : NSObject  : NSObject //声明一个类
 4 {
 5     int _age;//设置一个成员变量
 6 }
 7 
 8 - (void)study;//声明一个study对象方法
 9 - (void)setAge:(int)age;//声明set方法
10 
11 @end
12 
13 
14 
15 @implementation Student //对声明的方法进行实现
16 
17 - (void)setAge:(int)age //set方法的实现
18 {
19     if(age <= 0)  //对不合理的值进行过滤
20     {
21         age = 1;
22     }
23 
24     _age = age;
25 }
26 
27 - (void)study  //study方法的实现
28 {
29     NSLog("%d岁的学生在学习",age);
30 }
31 
32 @end
33 
34 int main()
35 {
36     Student *stu = [Student new];//新建一个Student类型对象
37     [stu setAge :10];//调用set方法进行赋值操作
38     [stu study];// 对象调用对象方法
39     return 0;
40 }
set方法例子

 2> get方法

  ①作用:返回成员变量值

  ②命名规范

   *有返回值,返回值类型与成员变量类型相同

   *方法名跟成员变量名相同

   *不需要接收任何参数

 1 #import <Foundation.foundation.h>
 2 
 3 @interface Student : NSObject //声明一个类
 4 {
 5     int _age;//设置一个成员变量
 6 }
 7 
 8 - (void)study;//声明一个对象方法
 9 - (void)setAge:(int)age;//声明set方法
10 - (int)age;//声明get方法
11 
12 @end
13 
14 
15 
16 @implementation Student //对声明的方法进行实现
17 
18 - (void)setAge:(int)age //set方法的实现
19 {
20     if(age <= 0)  //对不合理的值进行过滤
21     {
22         age = 1;
23     }
24 
25     _age = age;
26 }
27 
28 - (int)age // get方法的实现
29 {
30     return _age;
31 }
32 
33 - (void)study  //study方法的实现
34 {
35     NSLog("%d岁的学生在学习",[stu age]);//get方法的调用
36 }
37 
38 @end
39 
40 int main()
41 {
42     Student *stu = [Student new];//新建一个Student类型对象
43     [stu setAge :10];//调用set方法进行赋值操作
44     [stu study];// 对象调用对象方法
45     return 0;
46 }
get方法例子

 3> 封装细节

 ①成员变量名以_开头,命名规范

  *作用1,让成员变量名与get方法名区分开

  *作用2,跟局部变量名分开,带_一般就是成员变量名

 1 #import <Foundation.Foundation.h>
 2 
 3 @interface Score : NSObject //声明Score类
 4 {
 5     int _cScore;//设置成员变量 _cScore
 6     int _ocScore;//设置成员变量 _ocScore
 7     int _totalScore;//设置成员变量 _totalScore
 8     int _averageScore;//设置成员变量 _averageScore
 9 }
10 
11 - (void)setCScore:(int)cScore;//声明set方法
12 - (int)cScore;//声明get方法
13 
14 - (void)setOcScore:(int)ocScore;//声明set方法
15 - (int)ocScore;//声明get方法
16 
17 - (int)totalScore;//声明get方法
18 - (int)averageScore;//声明get方法
19 
20 @end
21 
22 
23 @implementation Score //方法的实现
24 
25 - (void)setCScore:(int)cScore //set方法的实现
26 {
27     _cScore = cScore;
28     _totalScore = _cScore + _ocScore;//计算总分,监听成员变量的改变
29     _averageScore = _totalScore/2;//计算平均分
30 }
31 
32 - (int)cScore // get方法的实现
33 {
34     return _cScore;
35 }
36 
37 
38 - (void)setOcScore:(int)ocScore //set方法的实现
39 {
40     _ocScore = ocScore;
41     _totalScore = _cScore + _ocScore; //计算总分,监听成员变量的改变
42     _averageScore = _totalScore/2;//计算平均分
43 }
44 
45 - (int)ocScore // get方法的实现
46 {
47     return _ocScore;
48 }
49 
50 
51 - (int)totalScore // get方法的实现
52 {
53     return _totalScore;
54 }
55 - (int)averageScore // get方法的实现
56 {
57     return _averageScore  ;
58 }
59 
60 @end
61 
62 int main()
63 {
64     Score *sc = [Score new];
65 
66     int t = [sc _totalScore];
67     int a = [sc _averageScore];
68 
69     NSLog("总分是%d,平均分是%d",t, a);
70 
71     return 0;
72 }
封装练习

 

 4> 封装的好处

  *过滤不合理的值

  *屏蔽内部的赋值过程

  *让外部不必关注内部细节

二、继承

1.继承

通过继承,子类可以拥有父类中所有的成员变量和方法

 1 #import <Foundation.Foundation.h>
 2 
 3 
 4 @interface Animal : NSObject //声明一个Animal类,并且继承了NSObject
 5 {
 6     int _age; // 声明了两个成员变量
 7     double _weight;
 8 }
 9 - (void)setAge:(int)age; //声明set方法
10 - (void)setWeight:(double)weight;
11 - int)age;  //声明get方法
12 - (double)weight;
13 - (void)run;
14 
15 
16 @implementation Animal //类的实现
17 - (void)setAge:(int)age //set方法的实现
18 {
19     _age = age;
20 }
21 
22 - (void)setWeight:(double)weight//set方法的实现
23 {
24     _weight = weight;
25 }
26 
27 - int)age //get方法的实现
28 {
29     return _age;
30 }
31 
32 - (double)weight //get方法的实现
33 {
34     return _weight;
35 }
36 
37 - (void)run
38 {
39     NSLog(@"动物跑了起来");
40 }
41 @end
42 
43 
44 
45 
46 
47 @interface Dog : Animal //Dog继承了Animal里面所有的成员变量和方法
48 
49 
50 @end
51 
52 
53 @implementation Dog
54 
55 @end
56 
57 int main()
58 {
59     Dog *d = [Dog new];
60     [d setAge:8];
61     [d setWeight:20.0];
62     NSLog(@"%岁的狗,%d公斤",[d age], [d weight]);
63     
64     return 0;
65 }
继承例子

2.重写

子类重新实现父类中某个方法,覆盖父类以前的做法

 1 #import <Foundation.Foundation.h>
 2 
 3 
 4 @interface Animal : NSObject //声明一个Animal类,并且继承了NSObject
 5 {
 6     int _age; // 声明了两个成员变量
 7     double _weight;
 8 }
 9 - (void)setAge:(int)age; //声明set方法
10 - (void)setWeight:(double)weight;
11 - int)age;  //声明get方法
12 - (double)weight;
13 - (void)run;
14 
15 
16 @implementation Animal //类的实现
17 - (void)setAge:(int)age //set方法的实现
18 {
19     _age = age;
20 }
21 
22 - (void)setWeight:(double)weight//set方法的实现
23 {
24     _weight = weight;
25 }
26 
27 - int)age //get方法的实现
28 {
29     return _age;
30 }
31 
32 - (double)weight //get方法的实现
33 {
34     return _weight;
35 }
36 
37 - (void)run
38 {
39     NSLog(@"动物跑了起来");
40 }
41 @end
42 
43 
44 
45 
46 
47 @interface Dog : Animal //Dog继承了Animal里面所有的成员变量和方法
48 
49 - (void)run;
50 @end
51 
52 
53 @implementation Dog
54 - (void)run //重写父类run方法
55 {
56     NSLog(@"%岁,%d公斤的狗跑了起来",[d age], [d weight]);    
57 }
58 
59 @end
60 
61 int main()
62 {
63     Dog *d = [Dog new];
64     [d setAge:8];
65     [d setWeight:20.0];
66     [d run];
67     NSLog(@"%岁的狗,%d公斤",[d age], [d weight]);
68     
69     return 0;
70 }
重写(例子)

3.super作用

 1> 直接调用父类中的某个方法

 2> super处在对象方法中,就调用父类的对象方法;super处在类方法中,就调用父类的类方法

 3> 使用场合:子类重写父类方法时,想保留父类方法的一些行为

4.使用注意

 1> 父类必须声明在子类前面

 2> 子类不能拥有和父类相同的成员变量

 3> 调用某个方法时,优先去当前类中寻找,如果找不到,再去父类中寻找

 4> oc语言是单继承

5.缺点

  *耦合性太强,删除父类后,子类就不能够继续使用

6.好处

  * 不改变原来模型的基础上,拓充方法

  * 建立了类与类之间的联系

  * 抽取了公共代码

7.使用场合

 1> 当两个类拥有相同的属性和方法时,就可以将相同的东西抽取出到父类中

 2> 当A类中拥有B类的部分属性和方法时,可以考虑让B类继承A类

 3> 组合:xxx拥有xx; 继承:xxx是xx

三、多态

1.多态:多种形态

 1> 没有继承就没有多态

 2> 代码体现:父类类型指针指向子类对象

#import <Foundation.Foundation.h>

@interface Animal : NSObject
- (void)eat;
@end

@implementation Animal
- (void)eat
{
    NSlog(@"动物吃东西");
}
@end

@interface Dog : Animal
- (void)eat;
@end

@implementation Dog
- (void)eat
{
    NSlog(@"Dog吃东西");
}
@end

int main()
{
    //多种形态
    Dog *d = [Dog new];// Dog类型
    
    //多态;父类指针指向子类对象
    Animal *a = [Dog new];
    
    [a eat];//调用方法时,检测对象的真实类型

    rerurn 0;
}
多态(例子)

2.优缺点

 1> 好处:如果函数\方法的参数类型使用的父类类型,可以传入子类和父类对象

 2> 局限性:父类类型变量不能够直接调用子类特有的方法(编译过程会有警告)。必须强转为子类类型便后后,才能够直接调用子类特有的方法。

四、自我总结

  面向对象的三大特性是面向对象语言的精华所在。面向对象是基于万物皆对象这个哲学观点。把一个对象抽象成类,具体上就是把一个对象的静态特征和动态特征抽象成相应的属性和方法,也就是把一类事物的算法和数据结构封装在一个类之中,程序就是多个对象和互相之间的通信组成的。面向对象具有封装性,继承性,多态性,封装隐蔽了对象内部不需要暴露给外人的细节,使得内部细节的变动跟外界不相关,只单纯依靠提供的接口进行通信。封装性降低了编程的复杂,通过继承,使得新建一个类变得更加容易,一个类从父类那里获得其方法和属性的工作就交给了编译器。而继承、实现和运行时的类型绑定机制所产生的多态,使得不同的类所产生的对象能够对相同的消息作出不同的反应,这极大地提高了代码的通用性。言而总之,面向对象的三大特性大大提高了程序的重用性和可维护性。

 

转载于:https://www.cnblogs.com/smqh/p/4245989.html

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐