封装和抽象是面向对象编程的四个支柱中的两个。这两个原则都有助于设计一个类,以便该类可以执行必要的功能,并且不会将不需要的细节暴露给其他类以避免其被滥用。
在这篇文章中,我们将详细了解抽象和封装,并讨论两者之间的一些差异。
简单来说,将数据(状态)和方法(行为)包装在一个类中,并结合信息和实现隐藏(通过访问控制)称为封装。
封装的结果是一个具有特征和行为的类。它可以与应用程序中的其他类交互以执行任何业务操作。
在以下示例中,ReportWriter 类具有 defaultLocation 属性,可以通过公共 setter 和 getter 方法访问该属性。它通过将属性设置为private 来防止直接设置该属性。
ReportWriter 还提供了 writeReport() 方法,该方法将在 defaultLocation 属性中设置的当前默认位置生成报告。这是封装的一个例子。
class ReportWriter {
private String defaultLocation;
public String getDefaultLocation() {
return defaultLocation;
}
public void setDefaultLocation(String defaultLocation) {
if(defaultLocation != null)
this.defaultLocation = defaultLocation;
}
public void writeReport(String reportType) {
//...
}
}
我在某处读到:“无论发生什么变化,都将其封装起来”。它被引用为著名的设计原则。就此而言,在任何类中,更改都可能发生在运行时的数据中,而实现的更改可能会在未来的版本中发生。因此,封装适用于数据和实现。
出于两个重要原因,访问控制或实现隐藏将边界置于数据类型或类中。
在任何一个类中,如果我们能够保证其他类只能通过public方法发送消息,那么我们以后修改类的非public成员就可以不用担心,也不会破坏类客户端代码。封装有助于我们实现这种保证。
抽象是在系统中创建抽象参与者的能力,这些参与者可以执行工作、报告和改变它们的状态,并与系统中的其他对象进行通信。 abstract actor 意味着,我们知道如何使用一个对象,但我们不知道它在内部是如何工作的。它使用访问修饰符隐藏了它的实现细节。
要使用此类抽象参与者,我们只需要了解我们将使用的公共 API。我们无需关心他们如何执行工作。
例如,在前面的 ReportWriter 示例中,我们定义了客户端必须用来生成报告的 writeReport() 方法。客户不必关心报告是如何生成的。
class ReportWriter {
public void writeReport(String reportType) {
//...
}
}
在学习abstraction时,我们了解到抽象本质上是一种思想,它有助于抽象类的行为。封装是我们实现所需抽象的机制。
简而言之,从 OOP 的角度来看,我们可以说:
以众所周知的类 HashMap 为例。 HashMap 类负责存储键值对,根据键进行搜索等。
从外部看,客户端代码只知道它的 get() 和 put() 方法。他们调用这些方法并快乐地生活。这本质上是抽象。抽象说客户端代码应该调用一个方法来添加键值对,一个方法来检索基于键的值等等。应该如何完成,与客户端代码无关。
封装就是在我们实现HashMap类的时候,写这些方法。我们编写 HashMap.Entry 类并创建一个类型为 Entry[]
的变量表。然后我们将所有这些声明为private 并授予public 仅访问put()
和get()
方法等.这其实就是封装。
封装是所需抽象的实现。
快乐学习!!
地址:https://www.cundage.com/article/encapsulation-in-java-and-its-relation-with-abstraction.html