-
Notifications
You must be signed in to change notification settings - Fork 0
/
oopde-na-dian-shi.html
358 lines (326 loc) · 21 KB
/
oopde-na-dian-shi.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:og="http://ogp.me/ns#"
xmlns:fb="https://www.facebook.com/2008/fbml">
<head>
<title>OOP的那点事 - 观测站</title>
<!-- Using the latest rendering mode for IE -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Open Graph tags -->
<meta property="og:type" content="article"/>
<meta property="og:title" content="OOP的那点事"/>
<meta property="og:url" content="https://zwy1135.github.io/oopde-na-dian-shi.html"/>
<meta property="og:description" content="隔了几个月,终于是又开始更新了。 最近在读《代码之髓》,略有心得,在此记述留赠有缘人吧。 废话不说,入正题。这次要写的是面向对象编程的话题。当然,我不会在这里絮叨class后面要加几个括号之类的细枝末节。这里要讲的是一些编程思想上的东西。 什么是类? 说起面向对象,最重要的话题就是类了。那到底什么是类呢?圈里一直有两种不同的看法: 1.类就是用户自己定义的数据类型,描述了数据以及数据的使用方法。 2.类是对程序中运行实体的描述,消息在实体之间传递并由实体来处理。 其实归结起来,还是那个老掉牙的统治与合作的话题。 第一种观点,我把它称为统治模式。它把由这种类建立起来的对象统统当作实现任务的工具,至于这些工具怎么使用,使用的效果怎样是由使用者决定的。打个拟人化的比方,对象的工作情况就像下面这段对话: 大哥,我会干这些这些事情,你给我排任务吧。 行,知道了,你说话,我照办。 大哥,这么干行不通啊。你拿个主意吧。 什么,你要我自己处理?!我不会,你就是打死我我也不会处理的。 这种思想指导下带来的结果是:你可以很方便的按照任务的划分把类建立起来,但是在被各种类或者对象组合起来使用的时候可能会出现各种诡异的麻烦。 具体表现就是 ..."/>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://zwy1135.github.io/theme/css/bootstrap.min.css" type="text/css"/>
<link href="https://zwy1135.github.io/theme/css/font-awesome.min.css" rel="stylesheet">
<link href="https://zwy1135.github.io/theme/css/pygments/native.css" rel="stylesheet">
<link rel="stylesheet" href="https://zwy1135.github.io/theme/css/style.css" type="text/css"/>
</head>
<body>
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="https://zwy1135.github.io/" class="navbar-brand">
观测站 </a>
</div>
<div class="collapse navbar-collapse navbar-ex1-collapse">
<ul class="nav navbar-nav">
<li >
<a href="https://zwy1135.github.io/category/machine-learning.html">Machine learning</a>
</li>
<li class="active">
<a href="https://zwy1135.github.io/category/reading-notes.html">Reading notes</a>
</li>
<li >
<a href="https://zwy1135.github.io/category/sui-bi.html">随笔</a>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="https://zwy1135.github.io/archives.html"><i class="fa fa-th-list"></i><span class="icon-label">Archives</span></a></li>
</ul>
</div>
<!-- /.navbar-collapse -->
</div>
</div> <!-- /.navbar -->
<div class="container">
<div class="row">
<div class="col-sm-9">
<section id="content">
<article>
<header class="page-header">
<h1>
<a href="https://zwy1135.github.io/oopde-na-dian-shi.html"
rel="bookmark"
title="Permalink to OOP的那点事">
OOP的那点事
</a>
</h1>
</header>
<div class="entry-content">
<div class="panel">
<div class="panel-body">
<footer class="post-info">
<span class="label label-default">Date</span>
<span class="published">
<i class="fa fa-calendar"></i><time datetime="2015-01-20T00:00:00"> 周二 20 一月 2015</time>
</span>
<span class="label label-default">Tags</span>
<a href="https://zwy1135.github.io/tag/oop.html">OOP</a>
/
<a href="https://zwy1135.github.io/tag/za-wu.html">杂物</a>
/
<a href="https://zwy1135.github.io/tag/notes.html">Notes</a>
</footer><!-- /.post-info --> </div>
</div>
<p>隔了几个月,终于是又开始更新了。</p>
<p>最近在读《代码之髓》,略有心得,在此记述留赠有缘人吧。</p>
<hr />
<p>废话不说,入正题。这次要写的是面向对象编程的话题。当然,我不会在这里絮叨class后面要加几个括号之类的细枝末节。这里要讲的是一些编程思想上的东西。</p>
<h3>什么是类?</h3>
<p>说起面向对象,最重要的话题就是类了。那到底什么是类呢?圈里一直有两种不同的看法:</p>
<div class="highlight"><pre><span class="mf">1.</span><span class="err">类就是用户自己定义的数据类型,描述了数据以及数据的使用方法。</span>
<span class="mf">2.</span><span class="err">类是对程序中运行实体的描述,消息在实体之间传递并由实体来处理。</span>
</pre></div>
<p>其实归结起来,还是那个老掉牙的统治与合作的话题。</p>
<p>第一种观点,我把它称为统治模式。它把由这种类建立起来的对象统统当作实现任务的工具,至于这些工具怎么使用,使用的效果怎样是由使用者决定的。打个拟人化的比方,对象的工作情况就像下面这段对话:</p>
<div class="highlight"><pre><span class="err">大哥,我会干这些这些事情,你给我排任务吧。</span>
<span class="err">行,知道了,你说话,我照办。</span>
<span class="err">大哥,这么干行不通啊。你拿个主意吧。</span>
<span class="err">什么,你要我自己处理?!我不会,你就是打死我我也不会处理的。</span>
</pre></div>
<p>这种思想指导下带来的结果是:你可以很方便的按照任务的划分把类建立起来,但是在被各种类或者对象组合起来使用的时候可能会出现各种诡异的麻烦。</p>
<p>具体表现就是:项目写到最后了,要把两个东西组合在一起用,但是这俩破玩意根本不兼容啊,赶紧改一改。什么,这俩破玩意都被几百个地方引用了,一个字母都不能改,怎么办怎么办!!!!!</p>
<p>第二种观点,我把它称之为合作模式。它把由这种类建立起来的对象都当作可以独当一面的大牛,对象与对象之间的合作就只需要发个消息就好。它工作起来就像这样:</p>
<div class="highlight"><pre><span class="err">这活要我来干?行我知道了。</span>
<span class="err">啊,这里出了问题。没事,我自己处理。</span>
<span class="err">都说了我自己处理了,你就别在旁边唧唧歪歪个不停了,干你自己的活去。</span>
</pre></div>
<p>这种思想导致了:把各种对象组合起来使用的时候异常舒爽,但是建立类的时候,要考虑让它天然的适配各种情况,坑的无比啊。</p>
<p>它的表现就是:工期过半了,项目进行的怎样了?什么,你还在写设计报告?!@¥%……&*(())</p>
<p>总而言之,这两种思想就是坑前期还是坑后期的选择,反正是要坑一边的,就看着坑吧。</p>
<h3>类的继承</h3>
<p>说了类,怎么也绕不过去的就是类的继承了。那到底怎么继承啊?现在主要有三种流派:</p>
<p>1、天下一统(一般化与专门化方法)</p>
<p>这种流派认为,作为父类的类应该定义所有一般化的方法,而子类呢就将这些方法专门化实现。</p>
<p>打个比方,现在有一个类叫做职猿,他有两个功能,领工资,干活。由他派生出两个子类:程序猿和设计猿。程序猿将这两个功能实现为领程序猿工资,干写代码的活。设计猿将这两个功能实现为领设计猿的工资,干设计的活。你想要一个除了领工资和干活外还会在公司里兴风作浪的家伙,不好意思,那不是职猿该干的事。</p>
<p>2、海纳百川(共有部分的提取)</p>
<p>这种流派认为,作为父类的类应该是子类共有功能的提取,子类各自实现自己的特殊化方法。</p>
<p>还拿职猿做例子。职猿是程序猿和设计猿的父类,程序猿和设计猿有什么共同的功能呢——领工资。那么职猿就实现领工资,由程序猿实现自己的写代码,设计猿实现自己的做设计。</p>
<p>3、随心所欲(仅仅将类作为代码复用的单位)</p>
<p>这种流派认为,哪来这么多乱七八糟的规矩,爷就是喜欢写类,就是喜欢继承。爷爱怎么干怎嘛干,就是任性你管得着吗!</p>
<h3>多重继承的天坑</h3>
<p>说了继承,就一定要说说多重继承的问题,多重继承有什么问题?还不就是那个命名冲突的问题嘛。</p>
<p>还是职猿那个例子。想像一下,公司里程序猿和设计猿干活干得好好的,突然出现了一个家伙,又能写代码又能做设计。那要怎么处理?那还不好办,从程序猿和设计猿多重继承出一个类,程序设计猿。好了,现在你下了一道命令,程序设计猿,干活去吧。他立刻就傻眼了,到底是该写代码还是该做设计啊?</p>
<p>那这个问题要怎么处理?还是三种方法:</p>
<p>1、禁止多重继承</p>
<p>既然命名冲突是多重继承导致的,那直接禁止多重继承不就好了。把公司里的程序设计猿都开掉,就没有任何问题了。那要是需要一个单位同时做程序猿和设计猿的工该怎么办?建立一个新类叫项目组。往里面放一个程序猿和一个设计猿,定义它的干活是程序猿干活并且设计猿干活,问题就解决了。这个新类还可以美其名曰托管类。</p>
<p>2、不预先作可能冲突的命名(MixIn方法)</p>
<p>既然干活这个方法会引起冲突。那就不预先定义这个方法好了,把各种待实现的功能定义成众多小类,由实际工作的终端类将他们组合起来,自己定义自己的干活方法好了。比如说定义一大串工作清单,领工资,写代码,做设计。再由程序猿继承写代码,再定义自己的干活为写代码。由程序设计猿继承写代码和做设计,再定义自己的干活为写代码和做设计。</p>
<p>3、由程序员指定选择的方法</p>
<p>你不是不知道要干什么嘛,我告诉你不就完事了……</p>
<hr />
<p>最后吧,其实类会引出这么多问题还是因为他的两个根本功能——作为对象实例的生成器和作为代码继承复用的单位——是相互冲突的。</p>
<p>作为对象实例的生成器要求类要大而全,其生成的对象要能独立工作。这往往导致了命名的冲突。</p>
<p>而作为代码继承复用的单位却要求类小而精,避免乱七八糟的冲突。这就导致了一堆不能生成对象,仅仅用来继承的模块类。真正能实用生成对象的类却没几个。</p>
<p>这个问题到现在都没有解决,只能留待后人的智慧了。</p>
<blockquote>
<p>Written with <a href="https://stackedit.io/">StackEdit</a>.</p>
</blockquote>
</div>
<!-- /.entry-content -->
<hr />
<section class="comments" id="comments">
<h2>Comments</h2>
<div id="disqus_thread"></div>
<script type="text/javascript">
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
var disqus_shortname = 'siteofz'; // required: replace example with your forum shortname
var disqus_identifier = 'oopde-na-dian-shi';
var disqus_url = 'https://zwy1135.github.io/oopde-na-dian-shi.html';
var disqus_config = function () {
this.language = "zh";
};
/* * * DON'T EDIT BELOW THIS LINE * * */
(function () {
var dsq = document.createElement('script');
dsq.type = 'text/javascript';
dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by
Disqus.</a></noscript>
<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
</section>
</article>
</section>
</div>
<div class="col-sm-3 well well-sm" id="sidebar">
<aside>
<section>
<ul class="list-group list-group-flush">
<li class="list-group-item"><h4><i class="fa fa-home fa-lg"></i><span class="icon-label">Social</span></h4>
<ul class="list-group" id="social">
<li class="list-group-item"><a href="https://github.com/zwy1135"><i
class="fa fa-我的github-square fa-lg"></i> 我的github
</a></li>
<li class="list-group-item"><a href="mailto:[email protected]"><i
class="fa fa-我的邮箱-square fa-lg"></i> 我的邮箱
</a></li>
</ul>
</li>
<li class="list-group-item"><a href="https://zwy1135.github.io/"><h4><i class="fa fa-home fa-lg"></i><span class="icon-label">Categories</span></h4></a>
<ul class="list-group" id="categories">
<li class="list-group-item">
<a href="https://zwy1135.github.io/category/machine-learning.html">
<i class="fa fa-folder-open fa-lg"></i> Machine Learning
</a>
</li>
</ul>
<li class="list-group-item">
<a href="https://zwy1135.github.io/category/reading-notes.html">
<i class="fa fa-folder-open fa-lg"></i> Reading Notes
</a>
</li>
</ul>
<li class="list-group-item">
<a href="https://zwy1135.github.io/category/sui-bi.html">
<i class="fa fa-folder-open fa-lg"></i> 随笔
</a>
</li>
</ul>
</li>
<li class="list-group-item"><a href="https://zwy1135.github.io/"><h4><i class="fa fa-tags fa-lg"></i><span class="icon-label">Tags</span></h4></a>
<ul class="list-group" id="tags">
<li class="list-group-item tag-1">
<a href="https://zwy1135.github.io/tag/scikit-learn.html">
Scikit-learn
</a>
</li>
<li class="list-group-item tag-1">
<a href="https://zwy1135.github.io/tag/machine-learning.html">
Machine Learning
</a>
</li>
<li class="list-group-item tag-1">
<a href="https://zwy1135.github.io/tag/python.html">
python
</a>
</li>
<li class="list-group-item tag-1">
<a href="https://zwy1135.github.io/tag/kaggle.html">
kaggle
</a>
</li>
<li class="list-group-item tag-3">
<a href="https://zwy1135.github.io/tag/za-wu.html">
杂物
</a>
</li>
<li class="list-group-item tag-4">
<a href="https://zwy1135.github.io/tag/oop.html">
OOP
</a>
</li>
<li class="list-group-item tag-4">
<a href="https://zwy1135.github.io/tag/ali.html">
ali
</a>
</li>
<li class="list-group-item tag-4">
<a href="https://zwy1135.github.io/tag/written-test.html">
Written Test
</a>
</li>
<li class="list-group-item tag-4">
<a href="https://zwy1135.github.io/tag/notes.html">
Notes
</a>
</li>
<li class="list-group-item tag-4">
<a href="https://zwy1135.github.io/tag/conda.html">
conda
</a>
</li>
<li class="list-group-item tag-4">
<a href="https://zwy1135.github.io/tag/sui-bi.html">
随笔
</a>
</li>
<li class="list-group-item tag-4">
<a href="https://zwy1135.github.io/tag/bokeh.html">
Bokeh
</a>
</li>
</ul>
</li>
<li class="list-group-item"><h4><i class="fa fa-external-link-square fa-lg"></i><span class="icon-label">Links</span></h4>
<ul class="list-group" id="links">
<li class="list-group-item">
<a href="http://getpelican.com/" target="_blank">
Pelican
</a>
</li>
<li class="list-group-item">
<a href="http://python.org/" target="_blank">
Python.org
</a>
</li>
<li class="list-group-item">
<a href="http://scikit-learn.org/stable/index.html" target="_blank">
Scikit-Learn
</a>
</li>
<li class="list-group-item">
<a href="http://www.kaggle.com/" target="_blank">
Kaggle
</a>
</li>
</ul>
</li>
</ul>
</section>
</aside> </div>
</div>
</div>
<footer>
<div class="container">
<hr>
<div class="row">
<div class="col-xs-10">© 2015 Zeng Wenyuan
· Powered by <a href="https://github.com/DandyDev/pelican-bootstrap3" target="_blank">pelican-bootstrap3</a>,
<a href="http://docs.getpelican.com/" target="_blank">Pelican</a>,
<a href="http://getbootstrap.com" target="_blank">Bootstrap</a> </div>
<div class="col-xs-2"><p class="pull-right"><i class="fa fa-arrow-up"></i> <a href="#">Back to top</a></p></div>
</div>
</div>
</footer>
<script src="//code.jquery.com/jquery.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="https://zwy1135.github.io/theme/js/bootstrap.min.js"></script>
<!-- Enable responsive features in IE8 with Respond.js (https://github.com/scottjehl/Respond) -->
<script src="https://zwy1135.github.io/theme/js/respond.min.js"></script>
<script type="text/javascript">
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
var disqus_shortname = 'siteofz'; // required: replace example with your forum shortname
/* * * DON'T EDIT BELOW THIS LINE * * */
(function () {
var s = document.createElement('script');
s.async = true;
s.type = 'text/javascript';
s.src = '//' + disqus_shortname + '.disqus.com/count.js';
(document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);
}());
</script>
</body>
</html>