我对 Java 中的封装感到困惑
I am confused about Encapsulation in Java
我多次研究封装,但我仍然不是 100% 清楚这个话题。
我的问题是:
getter 的真正作用是什么?假设我只使用 getter 而没有使用 setter,会发生什么?
setter 也一样。它到底做了什么,它是如何访问私有变量的?如果我只使用setter而不使用getter,会发生什么?
而且我们在 class:
中也有构造函数
class Car {
int x;
Car(int x) {
this.x = x;
}
}
对我来说,构造函数似乎与 setter 做同样的事情,尽管我“知道”它没有。因此,我也想对此进行澄清。
私有 - 只能在 class 内访问。让我们假设以下 class:
class Car {
private int x;
Car(int x){
this.x = x;
}
public int get(){
return this.x;
}
public void set(int x){
this.x = x;
}
}
现在另一个 class 并且您创建了 class car
的实例
class Car2 {
public static void main(String args[]){
Car c = new Car();
c.x = 5; // Do you think this will work?
int a = c.x; // this too?
}
}
(剧透)不会,因为它是私人的。
这就是我们使用函数(getter 和 setter)访问那些私有数据成员的原因。
构造函数的功能与setter相同,但不同的是,值将在对象创建时赋值。
例子:
Car c = new Car(5);
当创建对象 c
时,它的数据成员 x
将被赋值 5
.
封装正在使用访问修饰符控制对特定值的访问。考虑以下因素:
class Foo {
public int v;
public Foo(int v) {
this.v = v;
}
}
现在创建一个实例,Foo f = new Foo(20);
只需执行 f.v
即可访问 v。它可以通过 f.v = 30;
来改变
但是我出于某种原因 v
应该存储在列表或字符串中。您无法更改它,因为它会破坏现有用户的 class。这就是 getter 的用武之地。
class Foo {
private String v;
public Foo(int v) {
this.v = v+"";
}
public int getV() {
return Integer.parseInt(v);
}
}
以上是高度人为设计的,但它说明了可以更改值的内部处理而不影响访问该值的用户界面。因此,通过使用 getter(和 setters),可以执行以下操作:
- 确保用户界面始终return是预期值,而不考虑其内部性质。
- 允许用户在特定范围内设置一个值。因此 setter 可以在接受值之前对其施加限制。
- 制作防御性副本以防止更改内部值。例如,不要 return 一个数组,因为它可能会更改存储在实例中的数组。只是 return 数组的副本(或与此相关的任何其他数据结构)。
Imo,封装与抽象密切相关,因为抽象隐藏了事情如何完成的实现细节。封装隐藏 and/or 通过施加某种形式的访问控制来保护方法和变量。
我多次研究封装,但我仍然不是 100% 清楚这个话题。
我的问题是:
getter 的真正作用是什么?假设我只使用 getter 而没有使用 setter,会发生什么?
setter 也一样。它到底做了什么,它是如何访问私有变量的?如果我只使用setter而不使用getter,会发生什么?
而且我们在 class:
中也有构造函数class Car {
int x;
Car(int x) {
this.x = x;
}
}
对我来说,构造函数似乎与 setter 做同样的事情,尽管我“知道”它没有。因此,我也想对此进行澄清。
私有 - 只能在 class 内访问。让我们假设以下 class:
class Car {
private int x;
Car(int x){
this.x = x;
}
public int get(){
return this.x;
}
public void set(int x){
this.x = x;
}
}
现在另一个 class 并且您创建了 class car
class Car2 {
public static void main(String args[]){
Car c = new Car();
c.x = 5; // Do you think this will work?
int a = c.x; // this too?
}
}
(剧透)不会,因为它是私人的。
这就是我们使用函数(getter 和 setter)访问那些私有数据成员的原因。
构造函数的功能与setter相同,但不同的是,值将在对象创建时赋值。
例子:
Car c = new Car(5);
当创建对象 c
时,它的数据成员 x
将被赋值 5
.
封装正在使用访问修饰符控制对特定值的访问。考虑以下因素:
class Foo {
public int v;
public Foo(int v) {
this.v = v;
}
}
现在创建一个实例,Foo f = new Foo(20);
只需执行 f.v
即可访问 v。它可以通过 f.v = 30;
但是我出于某种原因 v
应该存储在列表或字符串中。您无法更改它,因为它会破坏现有用户的 class。这就是 getter 的用武之地。
class Foo {
private String v;
public Foo(int v) {
this.v = v+"";
}
public int getV() {
return Integer.parseInt(v);
}
}
以上是高度人为设计的,但它说明了可以更改值的内部处理而不影响访问该值的用户界面。因此,通过使用 getter(和 setters),可以执行以下操作:
- 确保用户界面始终return是预期值,而不考虑其内部性质。
- 允许用户在特定范围内设置一个值。因此 setter 可以在接受值之前对其施加限制。
- 制作防御性副本以防止更改内部值。例如,不要 return 一个数组,因为它可能会更改存储在实例中的数组。只是 return 数组的副本(或与此相关的任何其他数据结构)。
Imo,封装与抽象密切相关,因为抽象隐藏了事情如何完成的实现细节。封装隐藏 and/or 通过施加某种形式的访问控制来保护方法和变量。