通过公共方法访问私有成员变量
Access private member variables through public methods
我刚刚了解了OOP。我对班级中的私人成员有点困惑。
我看到了有关将变量成员设置为私有的示例,因此不会在其他任何地方更改它。
但另一方面,有公共方法(如 getName()
和 setName()
)来获取和设置私有成员 Name。
通过方法更改它和直接更改它有什么区别?谁能为我解释一下?
此模式的主要论点是本答案中所述的封装。
但不可否认的是,在您的name
示例中,没有太多的封装。
以下是 getter/setter 方法与公共字段的两个优点:
-
通过 setter 方法设置值时,您可以检查和拒绝无效值,而如果字段是公共字段,则无法控制为其分配哪些值。
-
您不需要提供 setter 和 getter 方法,因此您可以有效地将字段设置为只读或只写。
使用方法更改它可以让您更好地控制要应用于访问成员变量的逻辑。
例如,如果成员变量是readonly
变量,则可以省略set
方法的实现,以便没有人可以写入内容。
或者另一方面,如果你只想写入一个变量,不希望任何人稍后读取它,你可以实现set
方法。
setters 将为您提供的另一件事是,您可以在提交值之前进行验证。例如,如果您希望将某种格式的string
设置为成员string
变量,则可以在 setter
函数中检查它,如果它与模式匹配,则接受它,如果不匹配,则拒绝它。
通常,最佳做法是通过getters
和setters
更改/读取成员变量
作为一般经验法则,您希望as restrictive as possible
类属性和扩展点(私有>受保护>公共)。这在长时间运行且需要维护和重构的项目中尤其重要。
一旦使用了一段时间,就很难将您的属性从公共限制为受保护/私有,因为您不知道有多少其他类依赖于这些属性是公共的。另一方面,从私人放松到受保护/公共的创伤较小,因为您不必担心以前在没有该类的情况下访问该财产。
话虽如此,getter 和 setter 为您提供了与班级的私人成员互动的独特联系点。这在 OOP 中称为encapsulation
。这意味着您可以确保与这些属互的每个人都以相同且一致的方式执行此操作。一个愚蠢的例子是属性的规范化:
private String name;
public void setName(String name) {
this.name = StringUtils.capitalize(name);
}
您在这里确保设置名称的人不需要关心其大小写,因为您是通过 setter 强制执行的。这同样适用于 getter,根据需要应用业务规则。
将其与访问公共财产进行比较,然后每次使用它时都需要利用它......
最后,我想说的是,盲目地将getter和setter添加到您的对象中是一种bad practice
。仅当有充分理由存在这些访问器时,才提供这些访问器。例如:
class Person {
private name;
public Person(String name) {
this.name = name
}
public String name() {
return name;
}
}
您通常不会将名字设置为一个人,因此我们可以一起省略该二传手。但每个人都有一个名字。在这种情况下,您可以通过其构造函数强制执行它。这使得这种区别变得明确,增强了您的设计并防止您的对象处于不一致的状态。
阅读此论坛帖子。您可能会找到很多有价值的观点来理解这些概念。http://www.cplusplus.com/forum/lounge/101305/
以下示例类的 getter 和 setter 显示了很少的良好做法。我们需要使用const
类型限定符等。我们还可以验证实现中的值。
例如:-
class ClassName{
string name;
int age;
int weight;
public:
void setName(string strName);
void setAge(int iAge);
void setWeight(int iWeight);
string getName() const { return name; }
int getAge() const { return age; }
int getWeight() const { return weight; }
};
我可以总结以下使用访问器的充分理由:
- 让未来的变化更容易
- 行为与属性的封装
- 使您的公共接口免受更改的影响
- 设置不同的访问级别
- 在设置或获取之前验证值
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 将包含C样式数组的对象初始化为成员变量(C++)
- 为什么我不能在一个类的不同行中声明和定义成员变量?
- 在循环中按顺序遍历成员变量
- c++类声明时,相同的例程,不同的成员变量类型
- 如何从另一个文件继承私有成员变量和公共函数
- 在C++类中,是否必须初始化作为数组的成员变量
- 如何从子成员函数修改父公共成员变量
- 我可以在 C++ 中将数据成员/变量从其定义之外添加到结构中吗?
- 从私有成员变量的成员方法返回unique_ptr
- 在派生类中使用基类的私有成员变量的最佳方法
- 静态 constexpr 类成员变量对多线程读取是否安全?
- C++:是否可以使用非静态成员变量模板?
- 打印所有继承的类成员变量和方法
- 如何在复杂继承中访问静态成员变量
- 为什么我不能在返回 const 的布尔函数中为类成员变量赋值?C++
- 成员变量与函数概念检查