首页 > 代码库 > 类和封装的概念

类和封装的概念

类和封装的概念

什么是类?

    

    电脑一般而言是由CPU内存主板键盘硬盘等部件组合而成。

技术分享

    思考:学习电脑组装需要多少时间?学习电脑组装是都需要学习显示器,键盘,鼠标,主板等部件的设计与制造?

 

类的封装

我们可以把程序按某种规则分成很多"块",类与类之间可能会有联系,每个类都有一个可变部分(public)和一个不可变部分(private)。我们需要把可变部分和不可变部分分离出来,将不可变的部分暴露给其他类,而将可变的部分隐藏起来,以便于随时可以让它修改。这项工作就是封装。

 

类分为以下两个部分

  • 类的实现细节
  • 类的使用方式

技术分享

 

 

 

 

 

 

    类为什么需要封装

  • 当使用类时,不需要关心其实现细节。当我们创建类时,才需要考虑其内部实现细节。

    例如:普通用户使用手机,只需要学习如何发短信,打电话,拍照等等。而这些功能如何实现,则是手机开发工程师需要考虑的事情。     

  • 高内聚,低耦合移植时我们所追求的,用好封装恰恰可以减少耦合
  • 只要对外接口不改变,可以任意修改内部实现,这个可以很好的应对变化。
  • 类具有了简洁清晰的对外接口,降低使用者的学习过程。

 

 

如何将一个类封装

  • 根据经验:并不是类的每个属性都是对外公开的

           - 如:女孩子不希望外人知道自己的体重和年龄

           - 如:男孩子不希望别人知道自己的身高和收入

  • 而一些类的属性是对外公开的

           - 如:人的姓名,学历,国籍等

  • 必须在类的表示法中定义属性和行为的公开级别

           - 类似文件系统中文件的权限

 

    C++中类的封装

  • 成员变量:C++中用于表示类属性的变量
  • 成员函数:C++中用于表示类行为的函数
  • C++中可以给成员变量和成员函数定义访问级别

          - public     

          成员变量和成员函数可以在类的内部和外界访问和调用

          - private

          成员变量和成员函数只能在类的内部被访问和调用

 

示例代码:类成员的访问属性

struct Human

{

void sleep()

{

printf("I‘m sleeping...\n");

}

 

void work()

{

printf("I‘m working...\n");

}

};

 

struct Girl : Human

{

private:

int age;

int weight;

public:

void print()

{

age = 22;

weight = 48;

 

printf("I‘m a girl, I‘m %d years old.\n", age);

printf("My weight is %d kg.\n", weight);

}

};

 

struct Boy : Human

{

private:

int height;

int salary;

public:

int age;

int weight;

 

void print()

{

height = 175;

salary = 9000;

 

printf("I‘m a boy, my height is %d cm.\n", height);

printf("My salary is %d RMB.\n", salary);

}

};

 

int main()

{

Girl girl;

Boy boy;

Human human;

 

human.sleep();

 

girl.print();

 

boy.age = 19;

boy.weight = 120;

boy.height = 180; //Error: ‘int Boy::height‘ is private

 

boy.print();

 

boy.work();

 

return 0;

}

 

分析:

  1. 从我们通过boy.height = 180;修改boy对象中的身高的值时,编译时会产生错误。提示我们Boy::height这个成员变量是私有的。但是我们却可以在boy.printf()函数中修改height的值。所以我们可以知道:private的成员只能在类的内部被访问和调用
  2. 我们通过boy.age = 19;编译时并没有发生错误可以知道。类的public成员可以在类的外部修改,所以public的成员可以在类的内部和外界访问和调用
  3. 我们在Human这个类中没有明显定义类的成员属于private还是属于public,但是我们在main中调用它编译没有报错。说明struct定义的类默认public的。
  4. 我们可以在boy中使用Human类中的函数work();

 

类成员的作用域

    我们知道全局变量和局部变量都有作用域,那么类也有作用域吗?

 

示例代码:类成员的作用域

#include <stdio.h>

 

int i = 1;

 

struct Test

{

private:

int i;

 

public:

int j;

 

int getI()

{

i = 3;

 

return i;

}

};

 

int main()

{

int i = 2;

 

Test test;

 

test.j = 4;

 

printf("i = %d\n", i); // i = 2;

printf("::i = %d\n", ::i); // ::i = 1;

// printf("test.i = %d\n", test.i); // Error

printf("test.j = %d\n", test.j); // test.j = 4

printf("test.getI() = %d\n", test.getI()); // test.getI() = 3

 

return 0;

}

 

分析:

  1. 我们单纯打印printf("i = %d\n", i); i的变量是main函数内定义的i的值,而不是全局变量i=4的值。这是因为小范围作用域的值会覆盖大范围作用域的值。
  2. 我们使用::作用域解析运算符来使用默认全局变量i的值。
  3. 我们访问Test类中成员时,不能从外部直接访问类的成员,公有成员变量和成员函数也是不能直接访问,需要通过对象才能访问类的成员。如代码所示:访问类成员i变量,需要定义一个test对象,通过test对象才能访问i的值。
  4. 类成员的作用域都只在类的内部外部无法直接访问。也就是说不同类使用相同的类成员名不会发生冲突。实际上类与命名空间有点相像。

 

 

 

 

 

类和封装的概念