封装 - 为啥我使用 getter setter 将我的数据成员公开,如果我已经在课堂上声明它们是私有的

Posted

技术标签:

【中文标题】封装 - 为啥我使用 getter setter 将我的数据成员公开,如果我已经在课堂上声明它们是私有的【英文标题】:Encapsulation - Why I am using getter setter to make my data members public if I already declare them private in class封装 - 为什么我使用 getter setter 将我的数据成员公开,如果我已经在课堂上声明它们是私有的 【发布时间】:2017-09-22 01:07:16 【问题描述】:

我只想问,我们有一个班级,其中我们有两个私有数据成员说:

class Employee
private int empid;
private String empname;


我将它们声明为私有,这意味着我只能在 Employee 类中使用它们。那么,需要为数据成员创建 getter setter 并将它们公开。

希望你能解决我的问题。

【问题讨论】:

【参考方案1】:

这是一个很好的问题。您经常会看到代码示例使成员私有但通过 getter/setter 对公开它们,而 getter/setter 除了设置相应的成员之外没有做任何其他事情。

在我的书中,这根本不是封装。你不比让成员公开更好。尽管很多人不愿意这样做,但他们很乐意为所有成员自动提供访问器。

提供访问器的一个原因是能够进行输入验证。例如。如果你 empIds 有一个 checksum,你可以在 setter 中强制执行它。直接访问成员是不可能的。

在我看来,最好考虑一下这个对象将扮演的角色,看看它如何用最少的访问器来实现这个角色。否则你的代码可能会违反Law of Demeter。

【讨论】:

【参考方案2】:

您是绝对正确的,创建 setter/getter 或公开字段都以相同的方式违反封装,因此,如果您确实想封装私有字段,大概是因为您在面向对象的环境中工作,你不想使用这些东西。

关于为什么需要创建 setter/getter 的问题:大多数项目(有意或无意地)并不基于面向对象的设计。还有其他范式,其中数据和功能是分开的,因此如果有封装的话,封装起着次要的作用。

在 Java 世界中,通常拥有纯(或非常接近纯)数据结构(Bean),以及在这些 Bean 上工作的服务/组件/EJB/等(基本上可以访问所有字段)。通常这些架构将功能部分进一步拆分为诸如表示、业务、持久性(三层架构)之类的主题,或者创建可以访问所有相关领域的显式控制过程(例如 MVC 通常是如何完成的)。

一种方法是否比另一种更好可能是一个主观的讨论,但简短的回答是:它通常是一种不同的范式(不是 OO),这就是创建 setter/getter 的原因。

【讨论】:

以上是关于封装 - 为啥我使用 getter setter 将我的数据成员公开,如果我已经在课堂上声明它们是私有的的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能将自动实现的 getter 和 setter 与 List 一起使用? (统一,C#)

为啥在使用扩展语法复制对象后 getter/setter 不再工作?

在使用 JPA 映射类时,为啥有人要在 getter 或 setter 上添加注释?

为啥 Swift 不像 Java 或 C# 那样对属性使用 getter 和 setter?

JSR 303 Bean 验证 - 为啥使用 getter 而不是 setter?

JSR 303 Bean 验证 - 为啥使用 getter 而不是 setter?