如何透过现象看本质,真正理解“类”这个概念?

2020-10-15 14:51:51 +08:00
 Hlianbobo
最近看 python 的书,其中讲了一些关于面向对象和类的知识。我看了以后头脑当中产生很多困惑,在此写出来。还请各位老师点播。

我看后感觉类就是一个自定义函数包。例如自己定义一个函数包的名称叫 A,包里面包含了好几个方法(也就是函数) sin,cos,子类 B 里面包含了方法(函数) tan 。tan 的定义使用了类 A 中的方法 sin 和 cos 。tan=A.sin/A.cos

如果这就是类。那么我们直接定义几个全局变量 sin,cos,tan 。以后直接在程序中调用不就可以了?何必非要打包到 A 和 B 里面。以后再通过 A.sin A.cos 的方式调用呢?没有本质区别啊。看起来只是形式上不同。

不过反过来一想,我上面的理解肯定有有问题的。如果类仅仅是个自定义函数包。那么就不存在某语言是否支持类或某语言不支持类的问题了。喜欢使用类的程序员。直接自己定义一个全局变量叫做 A 。然后把 A 接收的参数传给内部的函数 sin 和 cos,不一样可以实现“类”的调用??哪有这种事。如果时这样 python 哪还有必要规定专门用 class 来定义类,用 def 来定义一个方法?
所以究竟什么是类。使用类相对于使用全局变量有什么区别?有什么优势?还请老师点播。
7013 次点击
所在节点    Python
76 条回复
AX5N
2020-10-15 19:49:01 +08:00
@Hlianbobo
“完全没学过这门语言。感觉读起来困难不小吧。另外做数据分析。数据挖掘对编程的技能要达到什么深度?”

编程有 2 个方面,一个是编程技巧,一个是软件工程。对于你们这些并非靠开发软件来吃饭的人来说,掌握编程技巧就行,所谓的编程技巧其实也就是熟能生巧而已。你问的“类”更偏向软件工程方面,你懂不懂都问题不大,有没有类都对你没太大影响。
qiumaoyuan
2020-10-15 20:09:12 +08:00
嗯…免不了无法分辨的杂音太多,各说各的。
ConradG
2020-10-15 20:21:48 +08:00
“类”在语法层面上,是“命名空间”的一个不完全实现。
而“命名空间”的语义表达一般是“在……的前提下 /范围内”。
namelosw
2020-10-15 21:38:25 +08:00
其实你理解的没错,a.f(p1, p2)本质上和 f(A, p1, p2)区别没有那么大。

但是有个区别,有了对象(不一定非得有类),你可以写出:
def f(o):
o.printSelf()

那么这个 o 是什么呢? o 既不是 A,也不是 B,它是可以 printSelf()的东西。

总得来说,几个 implication:
1. 面向对象不一定有类
2. 面向对象的主要效果是实现多态
3. 抽象不一定需要类,函数就可以。而且继承往往是万恶之源,可读性和扩展性反而经常没有编写良好的函数好。即便是组合也是正确使用的函数组合性更强。
4. 多态不一定非得面向对象,也有模式匹配之类的方式
5. 面向对象的好处是添加新类型容易,比如有 A B 新增 C 容易,添加新的操作难,加个新方法 foo()就要把每个类型改一遍
6. 以如下的形式使用函数会把 5 的优缺点反转过来:
def foo(o):
if o.type is A:
doThis()
if o.type is B:
doThat()
这样的好处是新加一个操作 bar()函数就很容易,但是新加一个类型 C 就要把所有的函数改一遍
7. 面向对象常见的设计模式 Visitor,就是在面向对象范畴内,将 5 的优缺点反转成 6,即加操作容易,加类型难。在语言没有很好的函数支持的情况下使用 Visitor 是可以理解的,比如老版的 Java,像在 Python 或者 JavaScript 这种函数比较好用的语言里使用 Visitor 是自讨苦吃并且对设计模式没有深入理解的行为
8. 5 和 6 的优缺点的 trade off 可以用一个叫做表达式问题(expression problem)的问题概括,典型的解决方案是 Haskell 的 type class,还有一些奇怪且难懂的解法比如 object algebra 。
9. 还有更多的 implication 过于深入,就不展开了……

PS:大家说的和我上面说的面向对象都是非正统面向对象,即 Simula / C++ / Java / Python 等等,即有关类+封装 /继承 /多态的面向对象。其实应该叫面向类才对。
正统的面向对象核心是对象和消息传递,比如 Smalltalk 和 Erlang(你没看错)。
crella
2020-10-15 22:02:25 +08:00
太好了,这贴劝退我学计算机,非常感谢
zouzou0208
2020-10-15 22:15:39 +08:00
@namelosw 解释的真好,我记得王垠有篇文章也说这个的。
Jianrry
2020-10-16 00:31:53 +08:00
所谓的类,其实就是一个概念.

比如说你是一个人,人就是一个类,而一个个具体的人就是一个个实例.

类由两部分组成:字段和方法.

字段就是人的属性,比如说体重多少 kg,长多少 cm .

方法就是人的行为,比如说吃饭,喝水等行为

这就是类.
levelworm
2020-10-16 01:12:20 +08:00
SICP 里有自己构建 oop 的内容,可以学习一下。
xdeng
2020-10-16 01:17:09 +08:00
你得学会从上帝视角看就明白了。
ispinfx
2020-10-16 07:14:13 +08:00
封装、继承、多态。
zrc
2020-10-16 07:47:35 +08:00
狗{吃屎} 对象{方法}
吃(狗屎) 方法(参数)
wanglufei
2020-10-16 07:52:07 +08:00
以类的方式组织代码,以对象的方式组织(封装)数据
summerwar
2020-10-16 09:05:22 +08:00
参考生物分类的界门纲目科属种,然后就能理解了
palmers
2020-10-16 09:22:27 +08:00
就是一类实体及操作该类实体的抽象 这么说好像还是比较抽象
Pzqqt
2020-10-16 10:00:19 +08:00
曾经我也沉迷于函数式编程无法自拔 看了好多资料都没法完全理解面向对象的编程思想
直到有一天在网上受到高人指点 看到这么一段代码 瞬间茅塞顿开
![]( https://www.png8.com/imgs/2020/10/55857f64f52a9d83.jpg)
someonedeng
2020-10-16 10:00:50 +08:00
@namelosw "正统的面向对象核心是对象和消息传递" "大家说的和我上面说的面向对象都是非正统面向对象" 好像见过这两派人在哪吵起来
shyrock
2020-10-16 10:09:25 +08:00
全局变量你也可以理解为是在‘全局’这个类里面定义的成员变量,全局这个类代表了当前宇宙最顶级的类。
chenyu8674
2020-10-16 10:12:51 +08:00
编程的本质是在机器能理解的东西和人能理解的东西之间做翻译
hhhsuan
2020-10-16 10:15:53 +08:00
确实可以不用面向对象,一味鼓吹面向对象是一种迷信
ID2333
2020-10-16 10:26:58 +08:00
封装只是一部分,而楼说的也知封装最基本的,现象都没看全,怎么看本质。。标题太大。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/715238

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX