为什么子类不能访问基类的private成员?为什么要这样设计?
来源:互联网 发布:下载高品质音乐的软件 编辑:程序博客网 时间:2024/06/07 16:00
看到很多朋友提问“为什么子类不能访问基类的private成员”?随后看到很多朋友回答“这是规范”“这是封装的特性”类似这样的回答。我觉得大家都是对的。但是有时候您需要关注提问的重点在于why?为什么Java要这样设计private?或者是Object Oriented为啥要这样设计这样的机制?
- 封装性:首先,private成员具有良好的封装性(encapsulation)。这个性质对于良好的设计来说是个重要的要素。因为良好的封装性会减小耦合的。服务代码可以定义public函数给客户代码。这样一来客户代码可以和服务代码并行开发。更重要的是,如果修改服务代码的内部实现也不需要改动客户代码。
- 子类也是客户代码:对于客户代码的理解最直接的就是调用这个类的代码,这个很好理解。更深入的理解就可以把客户代码延伸到这个类的子类。从这一点来说子类就是基类的客户代码。你定义了一个class,在里面写了些通用的方法,甚至申明了abstract方法要求别人来继承。这个时候基类里面的protect成员就是对外的API,因为这些方法对子类来说是可见的,你不能随意改动。这个时候如果这个成员是public或者protected就可能造成麻烦。对于API来说你不能随意改动。你能设想JDK里面的有些类的API改动的情况吗?至少我会抓狂的:)
- 访问权限扩大原则:延伸话题来说,还有就是Java对override的时候访问权限的限制。大家都知道Java的访问权限从小到大是:private-> default-> protected-> public。如果要override一个基类里面的方法,那么子类的这个方法的权限不能比被override的函数权限小。这样就导致一个隐性的问题:如果你的基类有public方法,那么它的子类里面都有这个方法的public属性。你不能把基类的这个方法private化。换句话说一旦定义了public函数,它的子类都要维护这个public方法。所以就算是方法也要小心地把它设为public。
当然如果这个基类到最终的子类都是你维护,或者这个类本身就是个非public的类,那么原则可以放宽。
顺便说一下,Eclipse有自动生成标准get/set函数的功能,所以生成get/set是很容易的事情,不要为了方便把成员都变成public。
譬如写了个基类Base,然后有人继承了Base:
可是有一天你发觉用ArrayList更好,你就把Base改成:
然后所有Base的子类都无法编译,直接调用到子类data域的类也无法编译。这就是噩梦,客户端程序员会用眼光追杀你:)
回过头来想,如果当初Base的data域是private,由get/set来访问,那么你可以轻松的修改Base, 子类无需改动:
作者:卢声远<michaellufhl@yahoo.com.cn>
- 为什么子类不能访问基类的private成员?为什么要这样设计?
- 为什么子类不能访问基类的private成员?为什么要这样设计?
- 为什么子类不能访问基类的private成员?为什么要这样设计? .
- 为什么子类不能访问基类的private成员?为什么要这样设计?
- 为什么子类不能访问基类的private成员(为什么要使用get,set方法)?为什么要这样设计?
- 子类继承父类的private成员,但是不能直接访问
- 为什么子类的访问权限不能低于超类的访问权限
- 为什么不能在子类的初始化列表里初始化父类的成员
- 为什么不能在子类的初始化列表里初始化父类的成员
- 为什么不能在子类的初始化列表里初始化父类的成员
- 通过protected,private继承的子类不能通过基类指针进行访问。
- 静态成员函数为什么不能访问…
- C++的const类成员函数(解释为什么非const成员函数不能访问const对象的数据成员)
- 子类为什么不能重写父类的静态方法
- 子类为什么不能重写父类的静态方法
- 子类为什么不能重写父类的静态方法
- 子类为什么不能重写父类的静态方法
- 子类为什么不能重写父类的静态方法
- linux下安装oracle 10g 的艰难之旅(中)
- 对话框最大化时,控件也随比例最大化或者还原
- cannot appear in a constant-expression
- JBPM4项目和tomcat6.0的兼容问题
- linux下安装oracle 10g 的艰难之旅(下)
- 为什么子类不能访问基类的private成员?为什么要这样设计?
- Android通过JNI调用驱动程序(完全解析实例)
- H264 TS/ES
- 如何将xtype: 'selectfield‘放到var定义的对象里
- madpaly 移植到 TQ2440 遇到问题madplay not found (2)
- const用法详解
- hadoop出现文件夹无法删除,Name node is in safe mode.
- 扩展Delphi主菜单
- <td>TD再长也不换行,只撑宽!!!!!</td>