我对 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 通过施加某种形式的访问控制来保护方法和变量。