你好!让我们将今天的课程专门用于封装,并立即开始示例 :)这是一个普通的汽水机。我有一个问题要问你:它是如何运作的?尽量提供详细的回答:杯子是从哪里来的,内部温度是如何保持的,冰是储存在哪里的,机器是怎么知道加哪种糖浆的等等?你可能没有这些问题的答案。很公平,因为不是每个人都使用这样的机器。他们现在不那么受欢迎了。让我们再举一个例子。您每天肯定会多次使用的东西。哦,这是一个主意!告诉我们Google 搜索引擎如何作品。它究竟如何搜索与您输入的词相关的信息?为什么某些结果排名靠前而不是其他结果?即使您每天都使用 Google,您也有可能不知道。不过没关系。你不需要知道这个。您可以在搜索引擎中输入查询,而无需考虑它是如何工作的。您可以从机器上购买苏打水,而不知道它是如何工作的。你可以在不了解内燃机工作原理的情况下驾驶汽车,甚至完全不了解物理学,即使在小学阶段也是如此。由于面向对象编程的主要原则之一:封装,这一切成为可能. 阅读有关面向对象编程 (OOP) 的各种文章,您一定已经了解到编程涉及两个常见概念:封装和隐藏。作者使用“封装”一词来表示一件事,然后再表示另一件事。我们将探讨这两个术语,以便您获得完整的理解。在编程中,封装的原始含义是将数据以及操作该数据的方法捆绑到一个单元(即“胶囊”)中。在Java中,类是封装的单位。一个类包含数据(字段)和处理这些数据的方法。这对您来说似乎是明显正确的方法,但在其他编程范例中,一切安排都不同。例如,在函数式编程中,数据与其操作严格分开。在 OOP 中,程序由胶囊或类组成,其中包含数据和处理该数据的函数。现在让我们谈谈隐藏。我们如何在不了解它们的组织方式或工作方式的情况下使用各种复杂的设备?很简单:他们的创造者为我们提供了一个简单方便的界面. 在汽水机上,界面是面板上的按钮。按下一个按钮,您就可以选择罩杯尺寸。按另一个,你选择口味。第三个负责加冰。这就是您需要做的全部。机器的内部组织并不重要。重要的是它的设计方式要求用户按下三个按钮才能获得苏打水。汽车也是如此。里面发生了什么并不重要。重要的是,当你踩右踏板时,汽车向前行驶,而当你踩左踏板时,它会减速. 这就是隐藏的意义。程序的所有“内部”都对用户隐藏。对于用户来说,这是多余的、不必要的信息。用户需要最终结果,而不是内部过程。让我们以
Auto
类为例:
public class Auto {
public void go() {
/* Some complicated things happen inside the car.
As a result, it moves forward */
}
public void brake() {
/* Some complicated things happen inside the car.
As a result, it slows down. */
}
public static void main(String[] args) {
Auto auto = new Auto();
// From the user's perspective,
// one pedal is pressed and the car accelerates.
auto.gas();
// The other is pressed, and the car slows down.
auto.brake();
}
}
下面是 Java 程序中实现隐藏的样子。就像在现实生活中一样:为用户提供了一个接口(方法)。如果用户需要程序中的汽车来执行操作,他或她只需调用所需的方法即可。这些方法内部发生的事情是多余的。重要的是一切正常。这里我们说的是实现隐藏。除此之外,Java还有数据隐藏。我们在关于getters 和 setters 的课程中写到了这一点,但复习一下这个概念也没什么坏处。比如我们有一个Cat
类:
public class Cat {
public String name;
public int age;
public int weight;
public Cat(String name, int age, int weight) {
this.name = name;
this.age = age;
this.weight = weight;
}
public Cat() {
}
public void sayMeow() {
System.out.println("Meow!");
}
}
也许你还记得上一课这个班级的问题吗?如果没有,让我们现在记住它。问题在于它的数据(字段)对所有人开放——另一个程序员可以轻松创建一只体重为 0、年龄为 -1000 岁的无名猫:
public static void main(String[] args) {
Cat cat = new Cat();
cat.name = "";
cat.age = -1000;
cat.weight = 0;
}
也许您可以密切关注您的同事是否创建了具有无效状态的对象,但最好排除创建此类“无效对象”的可能性。以下机制帮助我们实现数据隐藏:
- 访问修饰符(private,protected,package default)
- 吸气剂和吸气剂
- 控制对象的正确状态。上面有这样的例子。setter 和 private 修饰符确保我们的程序不会有重量为 0 的猫。
- 通过界面实现用户友好性。只有方法被“暴露”给外界。调用方法足以得到结果——完全没有必要深入研究它们如何工作的细节。
- 代码更改不会影响用户。我们在方法内部进行任何和所有更改。这不会影响该方法的用户:如果正确的代码之前是“auto.gas()”以应用油门踏板,那么它将继续如此。事实上,我们在 gas() 方法内部进行了一些更改,这对用户来说仍然是不可见的:和以前一样,调用者只是简单地接收到所需的结果。
GO TO FULL VERSION