西西河

主题:【原创】public,private,protected干啥用的 -- 东方射日

共:💬6 🌺7 新:
分页树展主题 · 全看首页 上页
/ 1
下页 末页
  • 家园 【原创】public,private,protected干啥用的

    在另一个网站上,有人问

    C++的CLASS中的public, protected, private三个关键字取消会怎样?取消了,但继承和多态都在。说白了,就是这3个keyword的好处。

    在下斗胆,回答了一下。不敢藏拙,贴出来等待河里的大鱼指正和补充。 (顺便骗点积分)

    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。这样,外部用户无法直接访问EngineA,但是PowerModule和所派生出来的PowerModuleA,PowerModuleB可以访问EngineA。

    现在你设计了一款汽车姑且命名为QSBC。(气死奔驰)。你准备使用上述你设计的动力模块的某一型号PowerModuleA。显然,你作为汽车设计者,你希望你的用户自能通过挂档、油门或刹车控制你的动力模块,你不希望你的用户不踩油门就直接发指令给动力模块加速。所以PowerModuleA的接口应该只能通过汽车内部访问。同时,你也不希望你的用户买了你的车自己进行改装,改成ASBC(爱死奔驰)。这里,你就使用了私有继承QSBC:private PowerModuleA。这样,外部用户无法直接访问PowerModuleA,只有QSBC可以。而且QSBC所派生出来ASBC也无法访问PowerModuleA。

    当然讲到这里,你会说,没有保护继承和私有继承,我可以使用类的组合啊,那也是表示"有一个"的关系。这里就涉及到了多态。是的,你使用类的组合可以写成:

    QSBC mycar {

    :

    PowerModuleA core;

    :

    }

    这也表示mycar "有一个"PowerModuleA 的关系。但是这一是破坏了封装。买了QSBC的人可以不踩油门,直接调用mycar.core.accelerate来加速。二是破坏了多态。显然,我调用mycar.accelerate和调用mycar.core.accelerate是截然不同的两个方法:"同名的不同方法有不同的行为",并不是"同一个方法在不同类中的不同行为"。如果你一定要定义上述也是多态,那么建议你重新设计一个全新理念的OO语言。

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

    另外,有一些常用的应用如命名的构造函数"Named Constructor"、singleton类等,都要求 private或protected。你自己可以搜搜。

    关键词(Tags): #oop(铁手)#面向对象(铁手)#封装(铁手)#继承(铁手)#多态(铁手)
    • 家园 花就一个字
    • 家园 如果没有这三个关键字

      就只有同一个package里的类能够访问,而不是等同于public的效果。

      如果类不属于任何一个包会怎样?

      不知道,不过可以编一小段试试

      • 家园 你指的是不用这些关键字的情况

        缺省属性是private,所以只有类中成员能够访问。

        我说的是取消这些关键字的情况,那么应当设置缺省属性为public。 就象C中的Struct

    • 家园 很好很好,说的非常清楚:就是为了控制让别人能看到的东西
      • 家园 多谢铁老大亲自捧场。我的目的......

        不是说明这三个关键字在控制accessibility的作用。因为我以前学习C++。很多书本在讲到这里的时候都着重在accessbility上。看了半天,我就记住了一个3x3的表格,说明了三种继承和三种成员属性的影响/关系。但是仍旧不明白这些有什么用。

        只有了解三个关键字在OO中的不同含义才真正了解这三个关键字的作用,也才会灵活使用这三个关键字。

        简单讲,public是"是一个"的关系,特性可遗传 (EngineA是一个EngineBasic,EngineBasic的特性遗传给EngineA)

        protected是"有一个"的关系,特性可遗传(PowerModule有一个EngineA,并且EngineA的特性可以遗传给下一代,在设计PowerModuleA时,可以更改EngineA的接口)

        private是"有一个"的关系,特性不可遗传(QSBC有一个PowerModuleA,并且PowerModuleA特性不可遗传,在派生的ASBC中,不可更改PowerModuleA的接口)

分页树展主题 · 全看首页 上页
/ 1
下页 末页


有趣有益,互惠互利;开阔视野,博采众长。
虚拟的网络,真实的人。天南地北客,相逢皆朋友

Copyright © cchere 西西河