封装和抽象之间的确切区别是什么?
当前回答
这些有些模糊的概念并不是计算机科学和编程所独有的。我想提供一些额外的想法,可能有助于其他人理解这些重要的概念。
简短的回答
封装——隐藏和/或限制对系统某些部分的访问,同时暴露必要的接口。
抽象性——从具体的现实、具体的对象或实际实例中去除某些特征,从而降低复杂性。
主要的相似之处在于,这些技术旨在提高理解能力和实用性。
主要的区别在于抽象是一种更简单地表示事物的方法(通常是为了使表示更广泛地适用),而封装是一种改变其他事物与事物交互方式的方法。
长回答
封装
下面是一个封装的例子,希望能让大家更清楚:
这里我们有一个Arduino Uno,还有一个Arduino Uno。封装是封装的一个很好的代表。
封装旨在保护某些组件不受外部影响和知识的影响,并公开其他组件应该与之交互的组件。在编程术语中,这涉及到通过访问修饰符隐藏信息,访问修饰符改变了某些变量和/或属性可以读写的程度。
但除此之外,封装还旨在更有效地提供这些外部接口。对于我们的Arduino示例,这可能包括漂亮的按钮和屏幕,这使得用户与设备的交互更加简单。它们为用户提供了简单的方法来影响设备的行为,并获得有关其操作的有用信息,否则将非常困难。
在编程中,这涉及到将各种组件分组为可分离的结构,如函数、类或对象。它还包括提供与这些构造交互的方法,以及获取关于它们的有用信息的方法。
封装在许多其他方面帮助程序员,尤其是提高代码的可维护性和可测试性。
抽象
尽管这里有许多其他的答案将抽象定义为泛化,但我个人认为这个定义是错误的。我想说泛化实际上是一种特定类型的抽象,而不是反过来。换句话说,所有的概括都是抽象,但并非所有的抽象都一定是概括。
以下是我对抽象的看法:
你会说这个图像是一棵树吗?很有可能你会。但它真的是一棵树吗?当然不是!它是一堆像素,看起来像我们可能称之为树的东西。我们可以说它代表了一棵真实树的抽象。注意,树的一些可视化细节被省略了。此外,它不生长,不消耗水,也不产生氧气。怎么可能呢?它只是屏幕上的一堆颜色,由计算机内存中的字节表示。
这就是抽象的本质。这是一种简化事物的方法,这样它们就更容易理解。你脑子里的每一个想法都是对现实的抽象。你脑海中的树和这张图片一样都不是真正的树。
在编程中,我们可以通过创建一个Tree类来利用这一点,其中包含模拟生长、水消耗和氧气生产的方法。我们的创造将代表我们对实际树木的体验,并且只包含我们真正关心的特定模拟元素。我们使用抽象作为一种用字节和数学来表示我们经验的方式。
抽象类
编程中的抽象还允许我们考虑几个“具体”对象类型(实际存在的类型)之间的共性,并在唯一的实体中定义这些共性。例如,我们的Tree类可以继承一个抽象类Plant,它有几个属性和方法适用于我们所有类植物,但删除了那些特定于每种植物类型的属性和方法。这可以显著减少代码重复,并提高可维护性。
抽象类和普通类的实际区别在于,抽象类在概念上没有“真正的”实例。构造一个Plant对象没有意义,因为它不够具体。每一种“真正的”植物也是一种更具体的植物类型。
此外,如果我们希望程序更加实际,我们可能需要考虑Tree类本身可能过于抽象的事实。实际上,每个Tree都是一种更具体的Tree类型,因此我们可以为这些类型创建类,例如Birch、Maple等,它们继承自我们的Tree类(现在可能是抽象的)。
JVM
另一个抽象的好例子是Java虚拟机(JVM),它为Java代码的运行提供了一个虚拟或抽象的计算机。它从本质上拿走了系统中所有平台特定的组件,并提供了一个抽象的“计算机”接口,而不考虑任何特定的系统。
的区别
封装与抽象的不同之处在于,它与事物的“真实”或“准确”没有任何关系。它不会删除某些组件以使其更简单或更广泛地适用。相反,它可以隐藏某些组件来实现类似的目的。
其他回答
封装隐藏了实现细节,这些细节可能是通用的,也可能不是专门的行为。
抽象提供了一种泛化(例如,在一组行为之上)。
这里有一个很好的阅读:抽象、封装和信息隐藏,作者是Object Agency的Edward V. Berard。
抽象:以一种简化的/不同的方式来呈现事物的想法,这种方式要么更容易理解和使用,要么更切合实际。
考虑一个发送电子邮件的类……它使用抽象来向你展示自己作为某种信使,所以你可以调用emailSender。发送(邮件,收件人)。它的实际功能——选择POP3 / SMTP、调用服务器、MIME转换等等,都被抽象了出来。你只看到你的信使。
封装:保护和隐藏对象私有的数据和方法的思想。它更多的是让某样东西独立且万无一失。
以我为例。我把我的心率从世界其他地方压缩起来。因为我不希望其他人改变这个变量,我也不需要其他人来设置它来让我运行。它对我来说至关重要,但你不需要知道它是什么,而且你可能根本不在乎。
环顾四周,您会发现几乎所有您接触到的东西都是抽象和封装的例子。例如,你的手机向你展示了一种抽象的功能,它能把你说的话传达给别人——掩盖了GSM、处理器架构、无线电频率以及其他无数你不理解或不关心的东西。它还封装了来自您的某些数据,如序列号、ID号、频率等。
这一切都使世界成为一个更美好的居住地
抽象
抽象是提取所有现有和可预见实现的公共属性和字段的过程。
例如: 轿车是轿车、掀背车、SUV、双门跑车、敞篷车的抽象概念。 Car将具有所有类型的汽车所共有的所有属性和字段。
封装
封装是对用户隐藏不需要的细节的过程。这个术语来自于胶囊。就像药物隐藏在胶囊里一样。各种机器和设备和设备的细节,从搅拌机,自行车,洗衣机,收音机,电视到飞机。您不希望用户可以看到机器的所有细节。
在编程方面: 让我们考虑一个等级汽车。 在下面的例子中,所有用户需要知道的是转动键(turnKey()方法),他不知道内部函数。用户不需要了解任何内部功能或内部组件。
在这种情况下,所有的私有方法都是内部函数,像“活塞p1”这样的私有字段是用户不需要知道的内部数据。
public class Car{
private void startMotor(){ //do something }
private void generateVoltage(){ //do something }
private void sparkPlugIgnition(){ //do something }
private void fuelFlowFromTankToInjector(){ //do something }
private void pushPistonsDown() {
p1.doAction();
p2.doAction();
//do something }
private void moveCrankShaft(){ //do something }
private Piston p1;
private Piston p2;
public void turnKey(){
startMotor();
generateVoltage();
sparkPlugIgnition();
fuelFlowFromTankToInjector();
pushPistonsDown();
moveCrankShat();
...
}
}
许多答案和例子都具有误导性。
封装是将“数据”和“对该数据进行操作的函数”打包到单个组件中,并限制对某些对象组件的访问。 封装意味着对象的内部表示通常隐藏在对象定义之外的视图中。
抽象是一种表示基本特性而不包括实现细节的机制。
封装:——信息隐藏。 抽象:——实现隐藏。
示例(c++):
class foo{
private:
int a, b;
public:
foo(int x=0, int y=0): a(x), b(y) {}
int add(){
return a+b;
}
}
foo类的任何对象的内部表示都隐藏在该类的外部。——>封装。 foo对象的任何可访问成员(data/function)都是受限的,只能由该对象访问。
foo foo_obj(3, 4);
int sum = foo_obj.add();
方法add的实现是隐藏的。——>抽象。
我读得越多,就越困惑。所以,我的理解是:
封装:
我们通常从外面看到手表,它的组件被封装在它的身体里。我们对不同的操作有某种控制。这种隐藏细节和公开控制(例如设置时间)的方式就是封装。
抽象:
到目前为止,我们一直在谈论手表。但我们没有具体说明是哪种手表。可以是数字的,也可以是模拟的,可以是手用的,也可以是墙用的。有很多可能性。我们所知道的是,这是一块手表,它显示时间,这是我们唯一感兴趣的东西,时间。这种隐藏细节和公开通用特性或用例的方法就是抽象。
推荐文章
- 什么是依赖倒置原则?为什么它很重要?
- 为什么在Python方法中需要显式地有“self”参数?
- c#中朋友的对等物是什么?
- 如何在方法中访问“静态”类变量?
- 为什么c#不提供c++风格的'friend'关键字?
- String, StringBuffer和StringBuilder
- 存储库和服务层的区别?
- DDD -实体不能直接访问存储库的规则
- 为什么STL如此严重地基于模板而不是继承?
- 如何在Objective-C中声明类级属性?
- 面向方面编程与面向对象编程
- c++中类似于java的instanceof
- 在python中遍历对象属性
- 将类代码分离为头文件和cpp文件
- 在PHP中使用getter和setter而不是函数或简单的公共字段有什么优点?