×

Loading...
Ad by
  • 推荐 OXIO 加拿大高速网络,最低月费仅$40. 使用推荐码 RCR37MB 可获得一个月的免费服务
Ad by
  • 推荐 OXIO 加拿大高速网络,最低月费仅$40. 使用推荐码 RCR37MB 可获得一个月的免费服务

从封装、继承、多态和实际应用简单说说我的看法

本文发表在 rolia.net 枫下论坛OO的主要特征是什么?对了,就是封装、继承和多态这三大特征。

首先从封装讲起,如果我们没有了public, private, protected这三个关键字,我可以合理地假设所有成员的属性应该是public的(我想你不会写一段代码唯一的功能就是自娱自乐)。那么这个时候,所有成员都是公开的,也就是说你所做的只是包装(pack)而不是封装(encapuslate)。这时候要求你提供一个类的实现,你除了接口说明,还必须附上一纸申明:"严禁使用func1、func2、func3....违者罚款xxx,跑圈xxx,引体向上xxx,腹部绕杠xxx......."

接着说继承。你是否理解共有继承、保护继承和私有继承的关系?简单讲,共有继承是个"是一个"的关系。保护继承和私有继承是一个"有一个"的关系。两者概念是不同的。这样我举个例子来说明吧。就那OO里面最常说事的汽车来讲。我是一个汽车发动机厂家,设计了一个基本型的发动机EngineBasic。然后在此基础上设计外销的发动机EngineA。此时,我们要用公有继承:EngineA: public EngineBasic。因为EngineBasic的所有特性(接口)我们同样实现在EngineA上,提供给用户使用。
现在你变成一个汽车厂家,你的任务是利用购买来的EngineA设计一个动力模块PowerModule。这时候我想你并不希望你这个模块的使用者绕过你的模块直接访问EngineA。但是显然你模块中的部件必需访问EngineA,那毕竟是你的核心部件啊。所以EngineA的接口应当只是对PowerModule内部可见,外部使用的人必须通过你的PowerModule才可以改变EngineA的状态。同时考虑到你的模块;可能使用在卡车上,也可能使用在Van上,也可能使用在小车上。也就是说你的PowerModule可能会有一些子型号PowerModuleA,PowerModuleB。所以你选用了保护继承:PowerModule:protected EngineA.
现在你设计了一款汽车姑且命名为QSBC。(气死奔驰)。你准备使用上述你设计的动力模块的某一型号PowerModuleA。显然,你作为汽车设计者,你希望你的用户自能通过挂档、油门或刹车控制你的动力模块,你不希望你的用户不踩油门就直接发指令给动力模块加速。所以PowerModuleA的接口应该只能通过汽车内部访问。同时,你也不希望你的用户买了你的车自己进行改装,改成ASBC(爱死奔驰)。这里,你就使用了私有继承QSBC:private PowerModuleA。

当然讲到这里,你会说,没有保护继承和私有继承,我可以使用类的组合啊,那也是表示"有一个"的关系。这里就涉及到了多态。是的,你使用类的组合可以写成:
QSBC mycar {
:
PowerModuleA core;
:
}
这也表示mycar "有一个"PowerModuleA 的关系。但是这一是破坏了封装。买了QSBC的人可以不踩油门,直接调用mycar.core.accelerate来加速。二是破坏了多态。显然,我调用mycar.accelerate和调用mycar.core.accelerate是截然不同的两个方法:"同名的不同方法有不同的行为",并不是"同一个方法在不同类中的不同行为"。如果你一定要定义这也是多态,那么建议你重新设计一个全新理念的OO语言。


好了,我想这大概足够说明public, private, protected这三个关键字的作用了。

另外,有一些常用的应用如命名的构造函数"Named Constructor Idiom"、singleton类等,都要求 private或protected。你自己可以搜搜。更多精彩文章及讨论,请光临枫下论坛 rolia.net
Report

Replies, comments and Discussions:

  • 工作学习 / 专业技术讨论 / C++的CLASS中的public, protected, private三个关键字取消会怎样?
    • It'll become C--
      • 但继承和多态都在。说白了,就是这3个keyword的好处。
    • 从封装、继承、多态和实际应用简单说说我的看法
      本文发表在 rolia.net 枫下论坛OO的主要特征是什么?对了,就是封装、继承和多态这三大特征。

      首先从封装讲起,如果我们没有了public, private, protected这三个关键字,我可以合理地假设所有成员的属性应该是public的(我想你不会写一段代码唯一的功能就是自娱自乐)。那么这个时候,所有成员都是公开的,也就是说你所做的只是包装(pack)而不是封装(encapuslate)。这时候要求你提供一个类的实现,你除了接口说明,还必须附上一纸申明:"严禁使用func1、func2、func3....违者罚款xxx,跑圈xxx,引体向上xxx,腹部绕杠xxx......."

      接着说继承。你是否理解共有继承、保护继承和私有继承的关系?简单讲,共有继承是个"是一个"的关系。保护继承和私有继承是一个"有一个"的关系。两者概念是不同的。这样我举个例子来说明吧。就那OO里面最常说事的汽车来讲。我是一个汽车发动机厂家,设计了一个基本型的发动机EngineBasic。然后在此基础上设计外销的发动机EngineA。此时,我们要用公有继承:EngineA: public EngineBasic。因为EngineBasic的所有特性(接口)我们同样实现在EngineA上,提供给用户使用。
      现在你变成一个汽车厂家,你的任务是利用购买来的EngineA设计一个动力模块PowerModule。这时候我想你并不希望你这个模块的使用者绕过你的模块直接访问EngineA。但是显然你模块中的部件必需访问EngineA,那毕竟是你的核心部件啊。所以EngineA的接口应当只是对PowerModule内部可见,外部使用的人必须通过你的PowerModule才可以改变EngineA的状态。同时考虑到你的模块;可能使用在卡车上,也可能使用在Van上,也可能使用在小车上。也就是说你的PowerModule可能会有一些子型号PowerModuleA,PowerModuleB。所以你选用了保护继承:PowerModule:protected EngineA.
      现在你设计了一款汽车姑且命名为QSBC。(气死奔驰)。你准备使用上述你设计的动力模块的某一型号PowerModuleA。显然,你作为汽车设计者,你希望你的用户自能通过挂档、油门或刹车控制你的动力模块,你不希望你的用户不踩油门就直接发指令给动力模块加速。所以PowerModuleA的接口应该只能通过汽车内部访问。同时,你也不希望你的用户买了你的车自己进行改装,改成ASBC(爱死奔驰)。这里,你就使用了私有继承QSBC:private PowerModuleA。

      当然讲到这里,你会说,没有保护继承和私有继承,我可以使用类的组合啊,那也是表示"有一个"的关系。这里就涉及到了多态。是的,你使用类的组合可以写成:
      QSBC mycar {
      :
      PowerModuleA core;
      :
      }
      这也表示mycar "有一个"PowerModuleA 的关系。但是这一是破坏了封装。买了QSBC的人可以不踩油门,直接调用mycar.core.accelerate来加速。二是破坏了多态。显然,我调用mycar.accelerate和调用mycar.core.accelerate是截然不同的两个方法:"同名的不同方法有不同的行为",并不是"同一个方法在不同类中的不同行为"。如果你一定要定义这也是多态,那么建议你重新设计一个全新理念的OO语言。


      好了,我想这大概足够说明public, private, protected这三个关键字的作用了。

      另外,有一些常用的应用如命名的构造函数"Named Constructor Idiom"、singleton类等,都要求 private或protected。你自己可以搜搜。更多精彩文章及讨论,请光临枫下论坛 rolia.net
      • Glad to see you back again, did you get a book to re-learn your const usage? ;-)
        • You r right
          本文发表在 rolia.net 枫下论坛I'm not a senior C++ programmer. I understand.
          Some time I abuse "const". I know some of them are just make no sense.

          Last time you said I didn't understand the source code. you are right, I didn't read all the source code. when I saw :
          class ALIST {
          public:
          void **items;
          int numOfItems;
          } ;
          I ignore the "**", I just assume the item is the pointer to next node, ans ALIST is just a node for MYLIST. It's My mistake.
          If you can read what I wrote base on this assumption, you can find out why I made mistakes in #2, #4, #5, #9, #10

          For the return of "new". I use C++ from 1998, believe me, all the UNIX/LINUX platform they will not return NULL. At lease I didn't see it. But I don't have lots exp. for Windows. Some people said MS didn't support C++ as good as UNIX. As my experience and the coding policy in my company, we never check NULL after "new" instead , must check exception "try-catch"

          If we talk about the iterator, I still suggest to return an iterator for add, remove, delete. If we have iterator, We don't need the function setto (should encapuslated). Please refer to those functions in STL::list
          iterator insert(iterator pos, const T& x)
          iterator erase(iterator pos)
          iterator erase(iterator first, iterator last)

          for the #8, you r right, My mistake to put const before, I should use const after: int size() const.

          SORRY FOR ALL MY CARELESS.更多精彩文章及讨论,请光临枫下论坛 rolia.net
      • MFC是C++应用的极致,每次interviewer津津乐道问C++的问题, 真想f...他们。
        • MFC是C++应用的极致? 如果你见过多重嵌套的 template应用,你就会知道C++还有其它的东西.
          • 确实,感觉C++就是冰山,MFC只是一个角
          • MFC那么庞大,写成那样已经不错了。template再嵌套, 也就是个小不点
        • 还有多重嵌套的 template继承, 保证看了头晕.
          • Visual C++ doesn't support template template, as I remember
          • 头晕就是好的?
        • Actually MFC is not good C++.
          • Good C++ can't make money. Just stay there for learning. Just kidding
            • MFC能赚钱并不说明它是C++应用的极致, 也不说明你对C++懂多少.
              • 我要是懂的多, 就不提问了。看你们这些回答问题这么牛的, 也都在打工, 真难为你们了。
          • "Actually MFC is not good C++. ", conceptual misunderstanding, MFC is not C++, MFC is written in C++, it's a *library*.
        • C++的大本营在Unix/Linux,说“MFC是C++应用的极致”那是在埋汰C++,MFC用的甚至不是真正的符合ISO标准的C++
          • 我又说错话了:)))。看来你们很不喜欢microsoft
          • 不太熟unix, 那上面有什么类似MFC的类库, 说来听听, 学习一下。
            • 给你两例子. BOOST: http://www.boost.org/. ACE: http://www.cs.wustl.edu/~schmidt/ACE.html. 先大概瞅一下, 还这么牛哄哄我也没办法.
              • 是你牛哄哄的吧? 我可一直很客气的:)))。 弄了点破大杂烩, 当宝了?
              • 要是MFC弄明白了, 你早成资本家了,在家数钱呢? 还用在这里混?
              • 这也叫产品? 知道你为什么头晕了。 是晕!!!
              • Boost is a C++ library, not a MFC-like library on Unix, I'm using boost/spirit every day on Windows.
                • And used ACE on Windows several years ago as well, they are not Unix only library, please give another example...