不同编程语言中获取器和设置器的使用

7 投票
10 回答
2385 浏览
提问于 2025-04-16 09:55

我知道关于获取器和设置器(getters和setters)的问题很多,但我找不到和我问题完全一样的。 我想知道人们在不同的编程语言中是否会改变使用获取器和设置器的方式。我是从C++开始学习的,老师教我使用获取器和设置器。以下是我的理解:

在C++(还有Java?)中,一个变量可以是公开的(public)或私有的(private),但不能混合使用。举个例子,我不能有一个只读的变量,但在类内部又能改变它。它要么全部公开(可以读取和修改),要么全部私有(不能读取,只能在类内部修改)。正因为这样(可能还有其他原因),我们才使用获取器和设置器。

在MATLAB中,我可以控制变量的“setaccess”和“getaccess”属性,这样我可以让某些东西变成只读(可以直接访问这个属性,但不能覆盖它)。在这种情况下,我觉得我不需要获取器,因为我可以直接用 class.property 来访问。

另外,在Python中,不使用获取器和设置器被认为是“Pythonic”的,只有在必要时才把东西放到属性里。我不太明白为什么在Python中可以有所有公开的变量,因为这和我在学习C++时学到的正好相反。

我只是好奇其他人对此有什么看法。你会在所有语言中都使用获取器和设置器吗?还是只在C++/Java中使用,而在MATLAB和Python中直接访问(这正是我现在在做的)?第二种选择被认为不好吗?就我而言,我只是在说简单的获取器和设置器(只是返回/设置值,不做其他事情)。

谢谢!

10 个回答

2

这要看你需要多抽象了。例如,我最近在处理一个文本对象时,需要用到获取器和设置器。在Direct3D的文本对象中,它只是保存了一个字符串类型的文本变量。而在Direct2D的文本对象中,就需要重新创建和缓存这些东西。如果我在设计最初的抽象时选择了公开变量,那我就得重新设计接口,还要修改所有依赖的代码。虽然我同意在某些类中使用获取器和设置器没什么意义,但确实有些情况下它们是必要的。

当然,拥有属性的编程语言就不需要这种东西。但从概念上讲,它们是一样的。定义一个变量的属性其实就是用获取器和设置器加了一些语法上的糖衣,而我支持这种语法糖,但这并不改变封装的本质。我不会因为不同的编程语言而改变我的封装设计。当然,关于封装是否是好事的社区观点又是另一回事——这可能就是你所看到的差异。在C++中,封装被高度重视,而在Python社区,大家对此就没那么在意了。

3

在任何编程语言中,所有的公共变量都是可以的。是的,我知道这和你学到的正好相反。

面向对象的理论说,应该有一个稳定的公共接口和一些私有变量,你可以随意操作这些私有变量,并且可以随心所欲地更改实现,而不影响公共接口。

这确实是对的。但不对的是,认为私有接口必须对其他类不可访问。这个想法在面向对象理论中是个错误。它听起来在纸面上很合理,但在实际操作中几乎没有好处,反而会带来很多问题。

举个例子,很多年前我需要在Delphi中对一个小部件进行子类化,让它的行为稍微不同一点。其实变化不大,只是有一点点不同。但我需要重写的代码调用了一个私有方法,所以我无法重写它。结果我不得不重写两个方法。当然,那个其他方法做的事情是非常内部的,所以我最后基本上不是在子类化这个小部件,而是在复制它,只因为我做了一个小改动。

面向对象理论声称这样做是对的,因为如果不这样做,天哪,可能我的子类在下一个版本的Delphi中就不工作了,如果超类内部的东西发生了变化!那又怎么样呢?在这种情况下,我只需要修复它就行了。

如果我使用了你内部数据的某些部分,那是我的问题。你不需要担心。你需要做的只是以某种方式标记“这部分是内部的,可能会改变,使用需谨慎”。但是当你作为一个库的开发者,主动阻止我使用内部部分时,你只是在给我制造麻烦。

我现在几乎专门用Python开发,快十年了,Python的开放性从来没有给我带来问题,实际上还帮了我好几次(因为我可以通过在运行时简单地修补代码来修复框架的错误)。而Delphi的标准面向对象模型有不同的保护级别,在我使用它的两年里给我带来了好几次麻烦。

面向对象理论实际上是错的。私有成员没有什么用处。一切都应该是公共的。根据我的经验,这适用于任何语言。

6

其实,getter和setter(还有那些隐藏这些功能的公共属性)相比于公共变量,改进并不大,而且它们很可能是“准类”的一个很好的标志。

撰写回答