为什么要使用getter和setter/访问器?

为什么要使用getter和setter/访问器?

技术背景

在面向对象编程中,类的字段可以直接暴露给外部访问,也可以通过 getter 和 setter 方法来访问。直接暴露字段虽然简单,但缺乏封装性,不利于代码的维护和扩展。而 getter 和 setter 方法则提供了一种更灵活、更安全的方式来访问和修改类的字段。

实现步骤

1. 定义私有字段

为了实现封装,通常将类的字段定义为私有(private),这样外部代码就无法直接访问这些字段。

1
2
3
4
5
public class Employee {
private String firstName;
private String middleName;
private String lastName;
}

2. 提供 getter 方法

getter 方法用于获取私有字段的值。通常命名为 getFieldName() 的形式。

1
2
3
public String getFirstName() {
return firstName;
}

3. 提供 setter 方法

setter 方法用于设置私有字段的值。通常命名为 setFieldName() 的形式。

1
2
3
public void setFirstName(String firstName) {
this.firstName = firstName;
}

核心代码

以下是一个完整的 Java 类示例,展示了如何使用 getter 和 setter 方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.highmark.productConfig.types;

public class Employee {
private String firstName;
private String middleName;
private String lastName;

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getMiddleName() {
return middleName;
}

public void setMiddleName(String middleName) {
this.middleName = middleName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getFullName() {
return this.getFirstName() + this.getMiddleName() + this.getLastName();
}
}

在 Python 中,可以使用 property 来实现类似的功能:

1
2
3
4
5
6
7
8
9
10
11
12
class Simple(object):
def _get_value(self):
return self._value - 1

def _set_value(self, new_value):
self._value = new_value + 1

def _del_value(self):
self.old_values.append(self._value)
del self._value

value = property(_get_value, _set_value, _del_value)

最佳实践

1. 封装行为

通过 getter 和 setter 方法,可以将与获取或设置属性相关的行为封装起来,方便后续添加额外的功能,如验证逻辑。

1
2
3
4
5
6
7
public void setSpeed(int speed) {
if (speed > 100) {
this.speed = 100;
} else {
this.speed = speed;
}
}

2. 隐藏内部表示

可以在 getter 和 setter 方法中隐藏属性的内部表示,同时使用另一种表示来暴露属性。

3. 控制访问级别

getter 和 setter 方法可以设置不同的访问级别,例如 get 方法可以是 public,而 set 方法可以是 protected。

4. 延迟加载

对于存储在数据库中的对象,可以使用 getter 方法实现延迟加载,只有在需要时才从数据库中获取对象。

1
2
3
4
5
6
7
8
9
protected YourType _yourName = null;
public YourType YourName {
get {
if (_yourName == null) {
_yourName = new YourType();
return _yourName;
}
}
}

常见问题

1. 破坏契约

在 setter 方法中添加验证逻辑可能会破坏之前的契约,因为这改变了方法的前置条件。因此,在添加验证逻辑时,需要谨慎考虑是否会影响现有代码。

2. 降低可读性

过多使用 getter 和 setter 方法可能会使代码变得复杂,降低代码的可读性。在简单的情况下,如果不需要额外的功能,可以直接使用公共字段。

3. 性能问题

虽然 getter 和 setter 方法的性能开销通常很小,但在性能敏感的场景下,可能需要考虑直接访问字段。不过,现代编程语言和编译器通常会对方法调用进行优化,性能差异可能并不明显。

4. 违反面向对象原则

在某些情况下,过度使用 getter 和 setter 方法可能会导致类变成简单的数据持有者,而失去了面向对象编程的本质。应该尽量让类提供有意义的操作,而不仅仅是字段的访问和修改。


为什么要使用getter和setter/访问器?
https://119291.xyz/posts/why-use-getters-and-setters-accessors/
作者
ww
发布于
2025年5月26日
许可协议