学习面向对象的特点

1、面向对象的三大特点:

  (1)封装:把客观事物封装成抽象类,达到“属性和方法的集和性”和“信息隐蔽性”;

  (2)继承:派生类可以继承基类的属性和方法;

  (3)多态:主要体现在函数覆盖上,覆盖是针对虚函数。

C++代码练习:

  1 #include <stdlib.h>
  2 #include <windows.h>
  3 
  4 #pragma pack(1)
  5 
  6 //////////////////////////////////////////////////////////////////////////
  7 // 面向对象三大特征之一:封装
  8 // 方法和属性包装成一个整体,并且具有信息隐蔽性
  9 class Desk
 10 {
 11 private:
 12     int height;
 13 public:
 14     void ToString()                    // 普通函数
 15     {
 16         printf("I'm nothing but a Desk !
");
 17     }
 18     virtual void SaySomething()        // 虚函数,派生类可以选择性的重写
 19     {
 20         printf("Hello, I'm a Desk !
");
 21     };
 22 
 23     // 纯虚函数,派生类必须重写,否则不能被实例化,类似于Java中的接口,Java中的接口函数必须实现,否则无法编译
 24     // 有纯虚函数的类叫做抽象类,抽象类无法实例化
 25     // 如果派生类没有重写纯虚函数的话,派生类也是抽象类
 26     virtual void DoSomething() = 0;    
 27 };
 28 
 29 //////////////////////////////////////////////////////////////////////////
 30 // 面向对象三大特征之二:继承
 31 // 派生类能够继承父类的属性和方法
 32 class SmallDesk : public Desk
 33 {
 34 public:
 35     void ToString()                    // 重写普通函数
 36     {
 37         printf("I'm not only a Desk. I'm a SmallDesk !
");
 38     }
 39     void SaySomething()                // 选择重写了虚函数,可以被调用
 40     {
 41         printf("Hi, I'm a SmallDesk !
");
 42     };
 43     void DoSomething()                // 必须重写纯虚函数
 44     { 
 45         printf("A SmallDesk did something!
");
 46         Sleep(100);
 47     }
 48 };
 49 
 50 class BigDesk : public Desk
 51 {
 52 public:
 53     void ToString()                    // 重写普通函数
 54     {
 55         printf("I'm not only a Desk. I'm a BigDesk !
");
 56     }
 57     // 此处没有重写虚函数,会调用对应的基类函数
 58 
 59     // 但是必须重写下面的纯虚函数,否则会在声明对象的时候产生错误:
 60     // error C2259: “BigDesk”: 不能实例化抽象类
 61     void DoSomething()                
 62     { 
 63         printf("A BigDesk did something !
");
 64         Sleep(100);
 65     }
 66 };
 67 
 68 // Desk是抽象类,因此不能定义函数: void VisitDesk(Desk desk)
 69 void VisitDesk(Desk& rfr);
 70 void VisitDesk(Desk* ptr);
 71 
 72 int main()
 73 {
 74 
 75     SmallDesk sd;
 76     BigDesk bd;
 77     sd.ToString();            // 重写了基类的函数,于是调用了派生类的函数
 78     sd.SaySomething();        // 重写了基类的虚函数,于是调用派生类的函数
 79     sd.DoSomething();         // 调用派生类的函数
 80 
 81     bd.ToString();            // 重写了基类的函数,于是调用了派生类的函数
 82     bd.SaySomething();        // 没有重写基类的虚函数,调用基类的虚函数
 83     bd.DoSomething();         // 调用派生类的函数
 84 
 85     //////////////////////////////////////////////////////////////////////////
 86     // 面向对象的三大特征之三:多态
 87     // 真正和多态相关联的,是函数的重写(即:覆盖),尤其是虚函数的重写,因为非虚函数的重写,基类指针无法调用
 88 
 89     // 1、通过指针完成多态
 90     // 如果采用默认或private方式继承,下面一句会产出错误:
 91     // error C2243: “类型转换”: 从“SmallDesk *”到“Desk *”的转换存在,但无法访问
 92     Desk* ptr = &sd;
 93     ptr->ToString();           // 调用基类的函数,即使派生类中已经重写
 94     ptr->SaySomething();       // 调用派生类的函数,因为派生类中重写了该函数
 95     ptr->DoSomething();        // 调用派生类的函数,派生类必须重写此函数,否则无法实例化
 96     
 97     // 多态真正的用途是在一个方法中,不需要知道派生类是什么,只需传入基类参数,即可访问形形色色的派生类
 98     VisitDesk(&bd);
 99 
100     // 2、通过引用完成多态
101     // 如果采用默认或private方式继承,下面一句会产出错误:
102     // error C2243: “类型转换”: 从“SmallDesk *”到“Desk &”的转换存在,但无法访问
103     Desk& rfr = bd;            
104     rfr.ToString();            // 调用基类的函数,即使派生类中已经重写
105     rfr.SaySomething();        // 调用基类的函数,因为派生类中没有重写
106     rfr.DoSomething();         // 调用派生类的函数,派生类必须重写此函数,否则无法实例化
107 
108     // 多态真正的用途是在一个方法中,不需要知道派生类是什么,只需传入基类参数,即可访问形形色色的派生类
109     VisitDesk((Desk&)sd);
110 
111     //////////////////////////////////////////////////////////////////////////
112     // 其它
113     printf("sizeof(Desk) = %d
", sizeof(Desk));    // 有虚函数的空类的大小为4字节,再加上一个整型变量,共8字节
114     system("pause");
115     return 0;
116 }
117 
118 void VisitDesk(Desk& rfr)
119 {
120     rfr.ToString();            // 调用基类的函数,即使派生类中有没有重写,也就是说,普通函数没有多态的效果
121     rfr.SaySomething();        // 首先看派生类中有没有重写,如果没有,则调用基类函数
122     rfr.DoSomething();         // 调用派生类的函数,派生类必须重写此函数,否则无法实例化
123 }
124 
125 void VisitDesk(Desk* ptr)
126 {
127     ptr->ToString();           // 调用基类的函数,不管派生类中有没有重写,也就是说,普通函数没有多态的效果
128     ptr->SaySomething();       // 首先看派生类中有没有重写,如果没有,则调用基类函数
129     ptr->DoSomething();        // 调用派生类的函数,派生类必须重写此函数,否则无法实例化
130 }

 输出结果:

I'm not only a Desk. I'm a SmallDesk !
Hi, I'm a SmallDesk !
A SmallDesk did something!
I'm not only a Desk. I'm a BigDesk !
Hello, I'm a Desk !
A BigDesk did something !
I'm nothing but a Desk !
Hi, I'm a SmallDesk !
A SmallDesk did something!
I'm nothing but a Desk !
Hello, I'm a Desk !
A BigDesk did something !
I'm nothing but a Desk !
Hello, I'm a Desk !
A BigDesk did something !
I'm nothing but a Desk !
Hi, I'm a SmallDesk !
A SmallDesk did something!
sizeof(Desk) = 8
请按任意键继续. . .
原文地址:https://www.cnblogs.com/zanzan101/p/3329741.html