什么是封装?它实际上是如何隐藏数据的?
搜索发现了一个简单的定义:数据隐藏。
但是,请考虑以下两个示例:
1)第一个示例:
Class Employee
{
public int age;
}
2)第二个示例:
Class Employee
{
private int age;
public int getAge(){return age;}
}
问题:
在上述两个指定的示例中,没有数据隐藏,因为 age
要么被其他人修改,要么被其他人查看。数据隐藏在哪里?封装在上述示例中有何帮助?
Searching turns up a simple definition: data hiding.
But, consider the following two examples:
1) First Example:
Class Employee
{
public int age;
}
2) Second Example:
Class Employee
{
private int age;
public int getAge(){return age;}
}
Question:
In both the above specified examples, there is no data hiding, as age
is either being modified by others or being viewed by others. Where is the data hiding? How does encapsulation help in the above examples?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
存在数据隐藏。第二个示例隐藏了值的存储方式。此外,第二个示例使该值对于类外部的代码为只读。通过拥有私有字段并通过方法或属性公开它们,您可以立即获得一些优势,其中包括:
请注意,封装不仅仅涉及访问控制。封装的主要用途是隐藏调用代码的实现细节。当调用代码想要检索一个值时,它不应该依赖于值的来源。在内部,该类可以将值存储在字段中或从某些外部资源(例如文件或数据库)检索它。 也许该值根本不存储,而是即时计算的。这对于调用代码来说应该不重要。
当您通过方法或属性公开该值时,您可以保护调用代码免受此类详细信息的影响,这也使您可以更改实现,而不会影响调用代码。
There is data hiding. The second example hides how the value is stored. Also, the second example makes the value read-only for code outside the class. By having private fields and exposing them through methods or properties you immediately gain some advantages, some of which are:
Note that encapsulation is not only about having access control. The primary use for encapsulation is to hide implementation details from calling code. When calling code wants to retrieve a value, it should not depend on from where the value comes. Internally, the class can store the value in a field or retrieve it from some external resource (such as a file or a database). Perhaps the value is not stored at all, but calculated on-the-fly. This should not matter to the calling code.
When you expose the value through a method or property, you shield calling code from such details, which also gives you the possibility to change the implementation, without affecting calling code.
封装将做什么的概念与如何实现分开。
封装是面向对象编程中一个非常重要的概念。它隐藏了应用程序中其他模块的数据。在示例 2 中,正如您所看到的,您只能使用 getter 方法获取年龄,但您只能将该值设置为该类内的私有成员,而不能设置为该类之外的私有成员。这就是封装的优点。
Encapsulation separates the concept of what something does from how it is implemented.
Encapsulation is a very important concept in Object Oriented Programming. It is hiding the data from other modules in the application. In your example 2, as you can see you can only get the age and that too using a getter method, but you can only set the value to the private member within that class and not outside it. This is the advantage of Encapsulation.
考虑一下这个变体:
在您的示例中,外部和内部使用整数,这很令人困惑。 (类似于显示 2 * 2 = 4 来解释乘法,但也忘记了 2 + 2 = 4)
Think about this variant:
In your example the outside and inside use an integer and that is confusing. (Similar to showing 2 * 2 = 4 to explain multiplication and forgetting that 2 + 2 = 4 too)
封装
简单来说就是数据隐藏
。让我们看看封装是如何发生的。
假设您创建一个 Employee 类并包含两个实例变量。姓名和工资。你不会把它们设为私有。现在,程序中的另一个类可以通过创建一个对象(如果是员工类)来访问这两个变量。所以我们想要的就是向外部班级隐藏这两个或工资信息。
如果我们想隐藏薪水,我们可以简单地将薪水声明为
private
变量。现在我们知道,即使另一个类创建一个对象并尝试像以前一样访问工资,它也不起作用。因为它是一个私有字段,只能由 Employee 类访问。现在我们已经隐藏了我们的数据。但假设我们需要一个人输入每个员工的薪资详细信息。
我会说得更清楚。
数据输入人员有3种类型的数据输入
woked_hours、OT和leave
(Emplyee类为此有3个变量)。我们希望此人输入这些详细信息,但我们
不希望
他看到
工资计算
是如何完成的。它是根据 Employee 类中的数学方程完成的。所以他无法自行计算和输入工资。但我们让他看到了最终的工资。我们创建了一个方法来获取员工类中的工资值。 他知道这一点
,他可以使用两种方法来访问这些隐藏字段。
set 方法和 get 方法。
所以他调用 getmethod。
是的,他可以看到
工资
信息。因为我们创建了返回工资的get方法。现在他尝试使用 set 方法输入新的工资金额来更改工资的当前值。所以他调用e.setSalary(1000);
但它给出了一个错误。为什么?因为在雇员类中没有写成的方法我们故意没有编写该代码,因为我们不希望他立即设置工资值。所以我们隐藏了一些信息,但有些信息我们仍然让他访问。我们授予他
只读
的访问权限。但不是为了薪水而写
。那么既然我们已经完成了封装,它不是很有用吗?
同样的方式,他可以
设置
这些字段woked_hours、OT和leaves
。对于这些字段,我们只授予他“写入”权限。我们故意不编写getter 方法
。如果您同时编写了 getter 和 setter,那么您就允许他读取/写入这两种访问权限。仅设置或获取并不重要,该字段是私有的,该字段已被隐藏,数据已被隐藏。但某些访问权限是通过
getters
和setters
提供的。Encapsulation
isdata hiding
simply.let's see how encapsulation happens.
Assume you create a Employee class and include two instance variables. name and salary. You don't make them private. Now what happens another class in the program can access these two variables simply by creating an object if the employee class. So what we want is to hide these both or salary information to outside classes.
If we want to hide salary We can simply declare salary as a
private
variable. Now we know even another class create an object and try to access salary as before it doesn't work. Because it is a private field which is only accessible to Employee class. Now we have hidden our data.But assume that we need a person to enter salary details of each of the employees.
I will make it more clear.
The data entering person has 3 types of data to enter
woked_hours, OT and leaves
(Emplyee class has three variables for this).We want this person to enter these details but we
do not want
him tosee
how thesalary calculation
is done. It is done according to the mathematical equation which is inside Employee class.So he cannot calculate and enter salary it self. But we let him see the final salary. there We create a method to get the value of the salary inside employee class. it is
He knows this, that there are two methods he can use to access those hidden fields.
set method and get method.
So hecall getmethod.
yes hecan see
thesalary
information. Because we have created the getMethod to return salary. Now he try to use set method to enter a new salary amount to change current value of salary. so he calle.setSalary(1000);
But it gives an error. Why? because in the employee class there is no method written asWe intentionally didn't write that code because we don't want him to set salary value straight away. So we have hidden some information but some we still let him access. We gave him access to
Read only
. Butnot Write
for salary.so wasn't it useful now that encapsulation we have done.
The same way as he is allowed to
set
these fieldswoked_hours, OT and leaves
. for those fields we have given him access to Write only. There we intentionally do not writegetter methods
. If you write bothgetter
and setter you are allowing him toREAD/ Write
both access.It doesn't matter only set or get, The field is private, the field is hidden already data is hidden. But some access is given through
getters
andsetters
.在第一个示例中,变量年龄设置为公共变量。在这里,当声明 Employee 类型的对象时,任何人都可以修改 meeber 年龄。
但是,在第二个示例中,变量 Age 实际上是私有的,只能从 Employee 类内部进行修改。这就是数据隐藏的情况。
在面向对象编程中,封装是指一个对象由另一个对象组成。这与继承相反,继承中对象可以扩展已经存在的类。
In your first example the variable age is set as a public variable. Here anyone can modify the meeber age when an object of type Employee is declared.
However, in your second example the variable age is actually private, and can only be modified from inside of the class Employee. This is the case of data hiding.
In object oriented programming encapsulation is when one object is composed of another. This is in contrast to inheritance where an object can extent an already existing class.
封装不仅仅是数据隐藏。封装允许您保留与该实体相关的所有数据和功能。此数据的可见性级别是一个相关但不相同的概念。例如,
Employee
对象包含所有员工数据和功能(方法)。请注意,这不是强制的,而是由面向对象语言启用的。如果您出生在 OO 时代,这对您来说可能听起来很自然,但这是从函数式编程到 OOP 的巨大飞跃,无论是概念(设计)还是支持这种范例的语言。
引用维基百科文章:
There is more to Encapsulation than data hiding. Encapsulation allows you to keep all the data and the functionality pertinent to an entity with this entity. Levels of visibility of this data is a related, but not identical, concept. E.g. an
Employee
object caries all employee data and functionality (methods) with it. Note that this is not enforced, but enabled by the OO languages.This may sound natural to you if you were born into the OO era, but this was the big leap from Functional Programming to OOP, both conceptual (design) and in languages that support this paradigm.
Quoting from Wikipedia article:
假设我这样使用你的代码:
在这里,除非我查看你的源代码,否则我绝对不知道
Employee
是如何计算其年龄的。据我所知,getAge()
可能看起来像这样:或者可能更复杂。我只是不知道。
因此,在第二个示例中, getAge() 仅返回一个私有成员变量这一事实对我来说是完全隐藏的。
Say I use your code like this:
Here, unless I look at your source code, I have absolutely no idea how
Employee
has calculated its age. For all I know,getAge()
could look like this:or perhaps something even more complicated. I just don't know.
So in your second example, the fact that
getAge()
just returns a private member variable is completely hidden from me.