3

这会激怒其他人吗?我更愿意看到:

 block.key(newKey);  // set the key for this block

 testKey = block.key();  // look up the key for this block

 block.setKey(newKey); // set the key for this block
 testKey = block.getKey(); // look up the key for this block

首先,“set”和“get”是多余的(因此增加了噪音,降低了可读性)。操作 (set/get) 由每个语句的语法定义。我理解超载。事实上,使用相同的确切标识符强化了这些是对象的相同属性。当我阅读“getKey()”和“setKey()”时,我可能不太确定。

其次,如果“get”和“set”被严格解释为setter和getter,那么如果与设置/获取值相关的其他语义,例如副作用,将是令人惊讶的。

我想这种偏见来自我的 Smalltalk 背景,但是在一个多态性工作得很好的世界里,如果没有“get”和“set”到处都是,我们不是会更好吗?试想一下,如果我们不必一遍又一遍地输入这三个字母,我们还能输入多少代码?!(舌头有点靠近脸颊)

有没有人有同感?

4

11 回答 11

4

C# 的设计者显然同意,并且在 StackOverflow 上,“C#”标签以 2:1 的比例超过了下一个最流行的语言。所以我怀疑你是在向合唱团讲道。

于 2009-08-05T01:48:45.533 回答
4

几种语言有不同的方法来处理 getter 和 setter。在Java 中有getName 和setName,在Qt 中有name 和setName。由于以下原因,我更喜欢 Java 方式:

  1. 如果您有一个称为驱动器的功能怎么办?它会导致您的班级开车,还是设置/获得开车?
  2. 打开建议后,您可以键入 get,然后获取所有 getter。如果您不记得所需的 getter 的名称,这将非常有用。
  3. 基于原因一,它将功能分成不同的组。你有做某事的函数,它们不以 get 或 set 开头(尽管它们可能应该以 do? 开头)。然后你有获取属性的函数,它们都以 get 开头。然后你有设置属性的函数,它们都以 set 开头。
于 2009-08-05T01:48:52.213 回答
3

对我来说,get前缀set让我的大脑在阅读代码时做的工作更少。当一致使用时,get/set方法可以更容易地 grep 标题,可能使类更容易学习和使用。我花费大量时间阅读代码与编写代码,所以额外的字符getset对我来说很好。

于 2009-08-05T01:48:01.293 回答
3

Java 语言目前没有属性,因此 getter/setter 语法已成为事实上的标准。如果您编写 Java 代码,那么您会很好地使用 Java 约定。这不仅是为了让其他程序员可以阅读您的代码,更重要的是,还构建了数百个其他 Java 框架来处理支持Java Bean样式 getter/setter 的对象。

例如,在Velocity 模板引擎中,您可以编写如下内容:

The answer is $block.key

以上将尝试调用:

block.getkey();
block.getKey();

如果您已经定义了 block.getKey(),那么一切都会正常工作。一般来说,最好遵循语言的约定。

于 2009-08-05T02:42:30.643 回答
2

使用“get”前缀访问器和使用“set”作为修改器前缀是一种因语言而异的做法,并且似乎在 Java 中最为普遍。例如:

  • 在 Python 中,您有属性的概念,因此访问器可能看起来像obj.foo,而修改器可能看起来像obj.foo = bar(即使在幕后调用方法)。类似的概念也存在于 Ruby 等语言中。所以在很多语言中,对访问器和修改器的调用看起来像是对实例变量的直接“调用”,而你永远不会看到像“setFoo”或“getFoo”这样的东西。
  • 诸如 Objective-C 之类的语言不鼓励使用“get”作为访问器前缀的做法,因此在 Objective-C 中你会看到类似[obj foo]and的调用[obj setFoo:bar]

我也不喜欢在 Java 中使用“get”作为访问器前缀的做法,但我确实看到了使用“set”作为修改器前缀的优点。也就是说,由于 Java 中流行的做法是前缀为“get”/“set”,所以我在自己的代码中继续这种趋势。

于 2009-08-05T01:55:09.053 回答
2

在 C++ 中,我只使用重载

int parameter() const { return m_param }
void parameter(int param) { m_param = param; }
于 2009-08-05T01:56:58.523 回答
2

一般来说,属性名称应该是名词,而方法名称应该是动词,因此上面示例中的属性将被称为“驱动程序”,而方法将被称为“驱动器”。当然会有重叠的情况,但总的来说这是可行的,并使代码更具可读性。

于 2009-08-05T02:02:43.443 回答
1

是的,java 中的 get/set 本质上是一种解决语言问题的方法。

将其与 c# 属性进行比较

http://www.csharp-station.com/Tutorials/Lesson10.aspx

或 python http://blog.fedecarg.com/2008/08/17/no-need-for-setget-methods-in-python/

我认为这是java最大的失败之一。

于 2009-08-05T01:49:31.620 回答
0

C# getter 和 setter 是“第一类”实体,在语法上与函数调用不同(尽管任何任意代码都可以在访问器的上下文中运行)。

我只在强迫我使用的语言中使用 get/set,比如 Objective-C。

于 2009-08-05T01:50:59.853 回答
0

您可以轻松地在代码库中搜索对getDrive()或的引用setDrive()。如果您的方法只是命名为“驱动器”,那么您在搜索时会得到更多的误报。

于 2009-08-05T02:07:35.200 回答
0

听,听。

我真的很喜欢 getter 和 setter 的特殊符号。CLU 做得最好:

  • p.x在表达式中使用等同于调用get_x(p)

  • 使用p.x := e(assignment) 等同于 call set_x(p, e)

如果对象的接口p没有导出get_xset_x,您将无法进行相应的操作。简单的。

让我们听听它的语法糖!

于 2009-08-05T05:57:06.357 回答