39.md 4.1 KB
Newer Older
W
wizardforcel 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
# 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() {}
} 
```

W
wizardforcel 已提交
29
在上述程序中,方法`getArea()`计算矩形的面积。 要计算面积,需要`length``width`。 因此,数据字段`length``width`和方法`getArea()`保持在`Rectangle`类中。
W
wizardforcel 已提交
30 31 32 33 34 35 36 37 38 39 40

* * *

## Java 数据隐藏

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

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

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

W
wizardforcel 已提交
41
*   **公开** - 随处可见
W
wizardforcel 已提交
42
*   **私有** - 仅在类内部可见
W
wizardforcel 已提交
43 44
*   **受保护** - 在包及其子类中可见
*   **默认** - 在包内可见
W
wizardforcel 已提交
45 46 47

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

W
wizardforcel 已提交
48
### 示例 1:使用`private`的数据隐藏
W
wizardforcel 已提交
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77

```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 
```

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

W
wizardforcel 已提交
80
如果尝试从`Main`类访问`age`字段,则会收到错误消息。
W
wizardforcel 已提交
81 82 83 84 85

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

W
wizardforcel 已提交
86
通过将`age`设为私有,我们可以限制来自类外的未经授权的访问。 这是数据隐藏。
W
wizardforcel 已提交
87 88 89

* * *

W
wizardforcel 已提交
90
### 示例 2:使用`protected`的数据隐藏
W
wizardforcel 已提交
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110

```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();
   }

} 
```

W
wizardforcel 已提交
111
**输出**
W
wizardforcel 已提交
112 113 114 115 116

```java
I am a teacher 
```

W
wizardforcel 已提交
117
在上述程序中,我们创建了一个`Person`类,其中包括`protected`字段`profession``protected`方法`displayInfo()`
W
wizardforcel 已提交
118

W
wizardforcel 已提交
119
我们已经从`Teacher`类(这是`Person`的子类)中访问了这些成员。
W
wizardforcel 已提交
120 121 122 123 124 125 126

* * *

## 为什么要封装?

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

W
wizardforcel 已提交
127
*   它有助于控制我们数据字段的修改。 考虑一种情况,我们希望类中的`age`字段为非负数。 在这里,我们可以确定年龄`private`并可以在方法`setAge()`中应用逻辑。 例如,
W
wizardforcel 已提交
128 129 130 131 132 133 134 135 136 137 138 139 140

```java
class Person {
   private int age;

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

W
wizardforcel 已提交
141
*   获取器和设置器方法提供对我们的类字段的只读或只写访问。 例如,
W
wizardforcel 已提交
142 143 144 145 146 147 148 149 150 151

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

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

* * *

W
wizardforcel 已提交
152
## 数据隐藏与封装形式
W
wizardforcel 已提交
153 154 155

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

W
wizardforcel 已提交
156
封装是指将相关字段和方法捆绑在一起。 这使我们可以实现数据隐藏。 封装本身并不是隐藏数据。