为了更好更方便地活着——爱上private
刚开始接触OOP的时候,打心底里我不喜欢private与protected。我声明一个public然后不直接用它,不就跟private一样吗?在某些场合下,我还能偷偷地用一下public变量,这不是更方便吗?所以,以前写的class,除了class几个字母外,其它的跟struct没啥区别。做了几个小项目之后,我终于浪子回头。下面进入今天的正题——爱上private吧。
理由1。。。
假如一个member value不是public,唯一能够访问它的就是friend和API。我想,没有人会希望在写程序的时候喜欢因考虑是否需要()而浪费时间。所以,将member value声明为private,直观上能帮助我们减少这方面搔首挠耳的时间。比如,下面的这个例子,
class AccessLevels
{
public:
int getReadOnly();
int setReadOnly();
int setWriteOnly();
...
private:
int readOnly;
int writeOnly;
...
};
使用的时候,我们会毫不犹豫地加上()。还不止这些,假如你将member value设置为public,有一天你头晕晕地在A脚本中对readOnly修改为0,然后再B脚本百思不得其解的时候,你就会发现private在保护你的menber value时起到的作用了。
理由2。。。
也许,上面的例子还不足以让你信服,就像当初我刚学OOP时抵触private一般。下面我们换个高级一点的角度来看待这个问题:封装。再来一个简单的例子.
class SpeedDataCollection
{
public:
void addValue(int speed); //添加新的数据
double averageSoFar() const; //返回平均速度
};
averageSoFar()的实现方式有两种,一种是添加一个成员变量,记录到现在为止所有速度的平均值。一种是调用的时候,收集所有速度值,然后再求平均值。
第一种方法会让SpeedDataCollection对象变大,多出的空间用于存放目前的平均值,累积总量,数据数量。但是averageSoFar十分高效。第二种方法不用记录很多内容,但是每次都需要计算,执行比较慢。
试想一下,在一台路边的测速装置上,能有多少内存能够使用。并且也不是每时每刻都需要平均速度,对于这种仪器,使用第一种方法比较合适。而假如我们要在屏幕上面显示当前赛车的平均速度,对于averageSoFar的性能要求就会非常高,所以采用第二种方式比较合适。而客户使用averageSoFar的时候,只会知道效果不错,但是却不用关心背后的实现方式。这就是使用private变量,也就是封装带来的好处,将member隐藏在接口后面,让所有可能的实现变得有弹性。
理由3。。。
最近在使用Unity3D开发游戏,虽然使用的是C#,但是由于使用了过多的public变量让人的确非常头痛。比如,NPC的状态使用一个state变量进行标记,在跑道上,NPC的状态千变万化,也就是在客户的代码上,不断地修改着NPC的状态。比如,使用了一个保护罩,在保护的时间再使用一个保护罩,每个保护罩在消失的时候就会将state从保护状态更改为非保护状态。那么第一个保护罩消失的时候发生了什么事呢?第二个保护罩还在,但是状态已经是非保护状态了。这个时候就非常头疼了,因为使用到state的客户端代码非常多,很难在茫茫人海中找到那个它(bug)。
假如state为private,那么访问它的只有SetState()与GetState(),那么当程序出问题的时候,我或许只需要关注这两个函数的实现方式即可。这多么让人惊讶!!!一开始使用public是为了方便,最后却发现private提供了更多的便利!!!
再举个栗子,我们在程序的后期取消了public ... state变量,那么有多少代码会受到影响呢?那往往是一个不可知的大量。
最后,为什么说使用private而不使用protected呢?##
客户是有相对的,比如,主函数中的代码可以是类的客户,而派生类也可以是客户。假如我们使用了protected,意味着在derived class中可以随心所欲地修改base class中的protected成员。把理由3照搬到这里来依然成立。由此可以看出,当存在继承的时候,base class中的protected与public同样不具备封装性。
为了更好更方便地活着——爱上private的更多相关文章
- Dnsmasq安装与配置-搭建本地DNS服务器 更干净更快无广告DNS解析
默认的情况下,我们平时上网用的本地DNS服务器都是使用电信或者联通的,但是这样也导致了不少的问题,首当其冲的就是上网时经常莫名地弹出广告,或者莫名的流量被消耗掉导致网速变慢.其次是部分网站域名不能正常 ...
- 采用ADM2483磁隔离器让RS485接口更简单更安全
采用ADM2483磁隔离器让RS485接口更简单更安全 摘要:本文介绍RS485的特点及应用,指出了普通RS485接口易损坏的问题,针对存在的问题介绍了以ADM2483为核心的磁隔离解决方案. 关键词 ...
- 正则表达式匹配可以更快更简单 (but is slow in Java, Perl, PHP, Python, Ruby, ...)
source: https://swtch.com/~rsc/regexp/regexp1.html translated by trav, travmymail@gmail.com 引言 下图是两种 ...
- 金蝶随手记团队分享:还在用JSON? Protobuf让数据传输更省更快(实战篇)
本文作者:丁同舟,来自金蝶随手记技术团队. 1.前言 本文接上篇<金蝶随手记团队分享:还在用JSON? Protobuf让数据传输更省更快(原理篇)>,以iOS端的Objective-C代 ...
- 更轻更快的Vue.js 2.0与其他框架对比(转)
更轻更快的Vue.js 2.0 崭露头角的JavaScript框架Vue.js 2.0版本已经发布,在狂热的JavaScript世界里带来了让人耳目一新的变化. Vue创建者尤雨溪称,Vue 2.0 ...
- EpiiServer 更快捷更方便的php+nginx环境定制化方案
EpiiServer是什么 更快捷更方便的php+nginx多应用部署环境. github仓库首页 https://github.com/epaii/epii-server gitee仓库 https ...
- 线程安全使用(四) [.NET] 简单接入微信公众号开发:实现自动回复 [C#]C#中字符串的操作 自行实现比dotcore/dotnet更方便更高性能的对象二进制序列化 自已动手做高性能消息队列 自行实现高性能MVC WebAPI 面试题随笔 字符串反转
线程安全使用(四) 这是时隔多年第四篇,主要是因为身在东软受内网限制,好多文章就只好发到东软内部网站,懒的发到外面,现在一点点把在东软写的文章给转移出来. 这里主要讲解下CancellationT ...
- Mockplus更快更简单的原型设计
更快更简单的原型设计 https://www.mockplus.cn/ Mockplus,更快更简单的原型设计工具.快速创建原型,一键拖拽创建交互,团队协作省事省力.微软.华为.东软.育碧.Oracl ...
- Google 开源的依赖注入库,比 Spring 更小更快!
Google开源的一个依赖注入类库Guice,相比于Spring IoC来说更小更快.Elasticsearch大量使用了Guice,本文简单的介绍下Guice的基本概念和使用方式. 学习目标 概述: ...
随机推荐
- Python开发【项目】:大型模拟战争游戏(外星人入侵)
外星人入侵 游戏概述: 现在准备用python开始搞一个大型游戏,模拟未来战争,地球人狙击外星人大战(其实就是小蜜蜂游戏2333),玩家控制一个飞船,用子弹歼灭屏幕上空的外星飞船:项目用到了Pygam ...
- Ubuntu18.04下安装比特币客户端
一.下载有两种安装方式:安装包和源码 二.安装1.通过安装包安装在https://bitcoin.org/en/download下载Windows,Mac OSX,Linux对应的安装包.安装过程比较 ...
- 数据展现-百度js绘图
echarts:酷炫的绘图效果 http://echarts.baidu.com/examples/#chart-type-calendar
- POJ -1062 昂贵的聘礼(前向星 && SPFA)
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u013497151/article/details/30299671 题目链接:id=1062&qu ...
- 代码处理 iOS 的横竖屏旋转
一.监听屏幕旋转方向 在处理iOS横竖屏时,经常会和UIDeviceOrientation.UIInterfaceOrientation和UIInterfaceOrientationMask这三个枚举 ...
- poi根据模板导出word文档
POI结构与常用类 Apache POI是Apache软件基金会的开源项目,POI提供API给Java程序对Microsoft Office格式档案读和写的功能. .NET的开发人员则可以利用NPOI ...
- Django model中数据批量导入bulk_create()
在Django中需要向数据库中插入多条数据(list).使用如下方法,每次save()的时候都会访问一次数据库.导致性能问题: for i in resultlist: p = Account(nam ...
- Python第二弹--------类和对象
Python中的任何一条数据都是对象.每个对象都由3部分组成:标识.类型和值.对象的标识代表该对象在内存中的存储位置(因此是不可更改的),对象的类型表明它可以拥有数据和值的类型. 创建 Dog 类根据 ...
- PAT 1137 Final Grading[一般][排序]
1137 Final Grading(25 分) For a student taking the online course "Data Structures" on China ...
- 使用scikit-learn 估计器分类
本章的几个概念: 估计器(estimator) 用于分类.聚类和回归分析 转换器(transformer):用于数据预处理回来数据转换 流水线(pipeline): ...