类内的函数与类本身关系是什么?类在传递到函数时发生了什么?对类的赋值对象操作时,原对象怎么变化?让我们用简单的代码和说明探讨下这些问题。
- 类内函数
简单来说,类的主要作用是封装,把相关的变量和函数做成一个整体。
类成员函数和普通函数其实本质上是一样的,都是把一系列的操作方法封装在一起,不同之处是类的成员函数能直接访问类内的成员变量。原因是成员函数隐藏了一个当前类对象。
如下一段常规的类定义和使用代码:
调用函数后,成员变量自然就变成了11。
因为语言的封装关系,我们没有看到这个类对象。
当我们用Python定义类的时候,我们可以揭开这一层,清楚的看到这个类对象:
Python的每个成员函数第一个参数就是当前对象,我们调用的时候虽然不用写,但是他是真实存在的。函数内部也是通过这个self对象访问类内的其他成员变量。
再看一个更加清晰的玩法:
Go语言在函数前加一个类对象声明,将函数与结构绑定在一起,充分体现了变量和函数是完全分离的,只是函数通过类对象与变量关联在了一起。
- 对象传递
- 基础类型与引用类型
先看一个最基础的变量传递:
很明显,b和a是两个东西,b只是把a的内容复制了。
然后是一个对象的传递:
这里ojba和objb是两个变量,但他们是同一个东西,因为他们都是指向那个new Pack()。所以对objb的操作其实就等于对obja的操作。
换句话讲就是每个变量都占用一个内存,都是一个新的东西,但是基础类型里面直接就存了值,而对象变量里面存的是对象的实际位置(也就是每次调用new出来的那玩意)。
基础类型就是那些int、float、double... String也可以理解为基础类型。说的简单粗暴一点就是:凡是不需要使用new就可以整出来的变量都可以理解为基础类型。
-
- 形参和实参
形参就是函数声明的参数,而实参是传入的实际参数。
改写前面的代码:
函数传递参数时其实是创建了一个新的变量,这里其实就等价于前面的Pack objb = obja;
所以就很好理解为什么基础类型传递到函数里面完全不会影响外面的变量,而类类型传递进入函数后,函数内操作了类对象,原来的对象就会改变。
再看一个简单例子:
这里充分体现了objb是一个新的变量,当他指向一个新的对象时,和原来的obja半毛钱关系也没有。
如果硬要在函数里面改变外部对象,让他指向一个新new出来的对象怎么办?
关于这个,有些语言可以搞有些不能,比如C++可以指针或者引用,C#可以ref或者out。
就像这样:



