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

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 来定义一个方法?
所以究竟什么是类。使用类相对于使用全局变量有什么区别?有什么优势?还请老师点播。
6708 次点击
所在节点    Python
76 条回复
cmdOptionKana
2020-10-15 14:58:13 +08:00
你这需要补充 “面向对象” 的基础知识,一般是 Java 书里讲这个比较透彻。但你不用学 Java,那代码不学也能看明白的,主要是理解思想。
hello2060
2020-10-15 14:59:04 +08:00
这就是面向对象啊,类不仅是函数,还有成员变量。

你想象有一个类 person, 有 firstname, last name

有一个函数,要用到人的全名,怎么办,那这个函数里面就是 obj.getFirstName() + obj.getLastName()

所有用到人名字的函数都有这么一个运算,

那如果有一天这个类加了一个 midname 怎么办?所有的函数都要改?

所以不如这个类提供了一个 getFullName(), 外部直接调用 而不需知道内部实现
rogwan
2020-10-15 15:09:35 +08:00
类可以理解为上一层的封装。鸭子是类,实例就是各只鸭子;禽也可以是类,实例就是各种鸡鸭鹅;雉科也可以是类,实例就是各种鸟 /家禽都算... 以此类推,形成父类子类。如果只写一个基类“生物”,也没什么不可以。
hoyixi
2020-10-15 15:12:35 +08:00
封装只是一个方面,还有继承和多态

看你的描述,应该以前没怎么接触过编程,或者没接触过支持面向对象的编程语言。 理论终归是理论,面向对象就是一套套路,多看别人写的比较好的代码,自己多写,才能体会到底套路怎么玩的~

编程是工程性的,工科就是要动手,光看书是没用的
Hstar
2020-10-15 15:21:54 +08:00
我总结,一是为了方便代码复用,二是为了逻辑易懂,三是为了保护内部私有函数和变量,但主要就是为了方便代码复用,加快开发速度。
至于为什么类能方便代码复用,多写写代码就知道了。
楼上提到的继承和多态在 python 中实现不太一样,没有多态只有参数默认值,继承还有多继承。仅此方面我觉得比 java 实现要好。
XiaoxiaoPu
2020-10-15 15:26:17 +08:00
面向对象是一种编程思想,并不受语言本身限制,C 语言也可以实现,例如 linux kernel 就大量的使用面向对象。只是缺少语言的原生支持,会比较繁琐,很多东西要你自己手写实现,容易出错。

类,是编程语言对面向对象的原生支持,基于类,可以更方便的实现面向对象编程。「某语言是否支持类或某语言不支持类」其实就是语言是否**原生**支持面向对象。
BoarBoar
2020-10-15 15:29:13 +08:00
你说得没错,就你这个例子来说真没多少区别
但是如果工程更大,代码量更多呢?想象一下一个文件里定义几百个变量,是不是既混乱,又额外消耗很多内存。再想象一下一个工程几百个文件,互相引用起来得多混乱。
面向对象正是随着代码规模的增加而出现的思想,把作用相近的变量抽象为类,本质就是为了提升代码可读性和复用性。
重要的是这种抽象的思维,类只是一个描述思维的符号,没有类的 c 语言用 struct 一样能某种程度上实现面向对象。
liuzhanpeng
2020-10-15 15:34:48 +08:00
类的出现是为了封装, 实现功能内聚; 这样就方便类与类之间的交互。以更贴合人的思维方式表现出现实中复杂的业务关系。
chaleaoch
2020-10-15 15:45:01 +08:00
这里有一个封装的概念.
命名空间的封装.
在一个就是生命周期.

还有就是面向对象的其他特性. 也就是面向对象思想将的那些乱七八糟的.


都是全局变量当然没问题. 但是定义多了就有问题了.不信你上 github 上看大一点的项目源码.
mightofcode
2020-10-15 15:53:21 +08:00
因为类是一个高度抽象的概念,高度抽象某种程度上就意味着不实用

根据我的经验,思考类的本质对提高你的编程水平不会有太大帮助
LongMaoz
2020-10-15 15:54:55 +08:00
封装 继承 多态 ,这是一种思想,一种概念.
比如说你是 Human,其他人也是 Human,那么你们就同样隶属于 Human'类',
Human 有眼口手鼻,你是通过 Human 类生成的实例,那么你也有眼口手鼻,
更通俗的讲就是你继承了 Human 的 DNA,所以你不会有翅膀,不会有腮,不会长尾巴,
因为这些特性是属于其他类,不属于 Human 的。
weizhen199
2020-10-15 16:03:29 +08:00
透过现象看本质就是大佬看你怎么写的代码 bug 又多又 tm 难理解。
就想了个简单容易的办法统一一下
Biwood
2020-10-15 16:04:49 +08:00
不妨先抛开编程语言,就说说现实生活中的类,也叫“类别”。

比如你叫小明,她叫小红,但是你俩属于同一个类:人类。

“人类”这个词语在中文里本身就是比较抽象的,因为“人这个类别”只是一个概念,而不是一个在现实中可以摸得到、看得见的东西,但是你可以写下来,可以说出来,可以理解它,并跟其他人沟通。

回到编程领域,你现在要跟机器沟通从而控制机器。机器之间的语言由 0 和 1 组成,但是人类总不能每天往电脑里输入 0 和 1 来吧,所以才有了五花八门的编程语言。而面向对象就是一种让人类更好懂的书写编程语言的思维方式,它符合人的语言结构。编程里的“类”就是现实中你写作文时用到的“类”,根本没那么复杂。
xuanbg
2020-10-15 16:07:03 +08:00
类就是对象模板,嗯,是面向对象的对象。不是搞对象的对象,也不是象棋里面那一对象😁
wzzzx
2020-10-15 16:09:32 +08:00
我个人觉得初学者没必要去搞的多清楚,你也没办法搞的很清楚的。做下去你就知道了,不管怎么解释,其实都特别的抽象
nutting
2020-10-15 16:11:06 +08:00
面向对象,这是一种想模拟真实世界概念模型的做法。你不要从编程技术上考虑。
lxk11153
2020-10-15 16:11:49 +08:00
qiumaoyuan
2020-10-15 16:15:05 +08:00
类的核心是一组关联比较紧密的属性,然后附带上一堆操作这些属性的方法。

当然,工作当中你会遇到各种奇葩的类的写法,比如写了一个方法内部的逻辑跟本类的属性完全无关的。只要知道这些写法是错误的,并且它们普遍存在,就连自己为了适应环境时不时也要写出这样的代码,但自己一个人做项目的时候绝对不允许并且有能力不出现这样的代码就行了。
qiumaoyuan
2020-10-15 16:17:42 +08:00
我觉得许多人对面向对象理解得稀里糊涂的,主要是环境使然。看似长篇大论能讲出来一堆东西,扪心自问一下,其实根本上说服不了自己。

不注意自己纠偏又没有对的人带,比较难走出来。
nutting
2020-10-15 16:17:55 +08:00
你是初学者,做的往往都是面向过程,顺序逻辑的一些编程。软件开发可不是这么简单,比如游戏啊,图形界面啊,要构建一个现实世界的镜像的,就需要面向对象概念了

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

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

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

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

© 2021 V2EX