# Java 封装

> 原文： [https://www.programiz.com/java-programming/encapsulation](https://www.programiz.com/java-programming/encapsulation)

#### 在本教程中，您将借助示例学习 Java 中的封装和数据隐藏。

## Java 封装

封装是面向对象编程的关键功能之一。 封装是指将字段和方法绑定在单个类中。

将类中的相似字段和方法捆绑在一起也有助于隐藏数据。

* * *

## 封装字段和方法

通常，封装是将相似代码包装在一个地方的过程。

在 Java 中，我们可以将在单个类中一起操作的字段和方法捆绑在一起。 例如，

```java
class Rectangle {
   int length;
   int breadth;
   public void getArea() {}
} 
```

在上述程序中，方法`getArea()`计算矩形的面积。 要计算面积，需要`length`和`width`。 因此，数据字段`length`，`width`和方法`getArea()`保持在`Rectangle`类中。

* * *

## Java 数据隐藏

数据隐藏是一种通过隐藏实现细节来限制我们的数据成员访问的方法。

封装还提供了一种隐藏数据的方法。

可以通过访问修饰符来实现数据隐藏。 在 Java 中，有四个访问修饰符：

*   **公开** - 随处可见
*   **私有** - 仅在类内部可见
*   **受保护** - 在包及其子类中可见
*   **默认** - 在包内可见

要了解更多信息，请访问 [Java 访问修饰符](https://www.programiz.com/java-programming/access-modifiers)。

### 示例 1：使用`private`的数据隐藏

```java
class Person {
   private int age;

   public int getAge() {
      return age;
   }

   public void setAge(int age) {
      this.age = age;
   }
}

class Main {
   public static void main(String[] args) {
      Person p1 = new Person();
      p1.setAge(24);
      System.out.println("My age is " + p1.getAge());
   }
} 
```

**输出**

```java
My age is 24 
```

在上面的示例中，我们有一个`private`字段`age`。 由于它是私有的，因此无法从类外部访问它。 为了访问`age`，我们使用了`public`方法`getAge()`和`setAge()`。 这些方法称为获取器和设置器方法。

如果尝试从`Main`类访问`age`字段，则会收到错误消息。

```java
p1.age = 24;     // error: age has private access in Person 
```

通过将`age`设为私有，我们可以限制来自课堂之外的未经授权的访问。 这是数据隐藏。

* * *

### 示例 2：使用`protected`的数据隐藏

```java
class Person {
 protected String profession;

 protected void displayInfo() {
   System.out.println("I am a " + profession);
 }
}

class Teacher extends Person {
   public static void main(String[] args) {
      Teacher t1 = new Teacher();
      t1.profession = "teacher";
      t1.displayInfo();
   }

} 
```

**输出**：

```java
I am a teacher 
```

在上述程序中，我们创建了一个`Person`类，其中包括`protected`字段`profession`和`protected`方法`displayInfo()`。

我们已经从`Teacher`类（这是`Person`的子类）中访问了这些成员。

* * *

## 为什么要封装？

*   在 Java 中，封装可帮助我们将相关的字段和方法保持在一起，这使我们的代码更整洁且易于阅读。

*   它有助于控制我们数据字段的修改。 考虑一种情况，我们希望类中的`age`字段为非负数。 在这里，我们可以确定年龄`private`并可以在方法`setAge()`中应用逻辑。 例如，

```java
class Person {
   private int age;

   public void setAge(int age) {
     if (age >= 0) {
        this.age = age;
     }
   }
} 
```

*   获取器和设置器方法提供对我们的类字段的只读或只写访问。 例如，

```java
getName()   // provides read-only access
setName()   // provides write-only access 
```

*   它有助于解耦系统的组件。 这些解耦的组件可以独立且同时进行开发，测试和调试。 并且，特定组件的任何更改都不会对其他组件产生任何影响。

* * *

## 数据隐藏与封装形式

人们通常将封装视为数据隐藏，但这并非完全正确。

封装是指将相关领域和方法捆绑在一起。 这使我们可以实现数据隐藏。 封装本身并不是隐藏数据。