封装和抽象之间的确切区别是什么?
当前回答
简而言之
抽象使用->封装 & 封装使用->数据隐藏
OR
数据隐藏是封装和的子集 封装是抽象的一个子集
参考:http://www.tonymarston.co.uk/php-mysql/abstraction.txt
其他回答
抽象和封装的区别。
另一个例子:
假设我创建了一个不可变的Rectangle类,如下所示:
class Rectangle {
public:
Rectangle(int width, int height) : width_(width), height_(height) {}
int width() const { return width_; }
int height() const { return height_; }
private:
int width_;
int height_;
}
现在很明显,我已经封装了宽度和高度(访问受到某种限制),但我没有抽象任何东西(好吧,也许我忽略了矩形在坐标空间中的位置,但这是示例的缺陷)。
好的抽象通常意味着好的封装。
一个好的抽象例子是通用数据库连接类。它的公共接口与数据库无关,非常简单,但允许我对连接做我想做的事情。你看到了吗?这里还有封装,因为类内部必须有所有低级句柄和调用。
这些有些模糊的概念并不是计算机科学和编程所独有的。我想提供一些额外的想法,可能有助于其他人理解这些重要的概念。
简短的回答
封装——隐藏和/或限制对系统某些部分的访问,同时暴露必要的接口。
抽象性——从具体的现实、具体的对象或实际实例中去除某些特征,从而降低复杂性。
主要的相似之处在于,这些技术旨在提高理解能力和实用性。
主要的区别在于抽象是一种更简单地表示事物的方法(通常是为了使表示更广泛地适用),而封装是一种改变其他事物与事物交互方式的方法。
长回答
封装
下面是一个封装的例子,希望能让大家更清楚:
这里我们有一个Arduino Uno,还有一个Arduino Uno。封装是封装的一个很好的代表。
封装旨在保护某些组件不受外部影响和知识的影响,并公开其他组件应该与之交互的组件。在编程术语中,这涉及到通过访问修饰符隐藏信息,访问修饰符改变了某些变量和/或属性可以读写的程度。
但除此之外,封装还旨在更有效地提供这些外部接口。对于我们的Arduino示例,这可能包括漂亮的按钮和屏幕,这使得用户与设备的交互更加简单。它们为用户提供了简单的方法来影响设备的行为,并获得有关其操作的有用信息,否则将非常困难。
在编程中,这涉及到将各种组件分组为可分离的结构,如函数、类或对象。它还包括提供与这些构造交互的方法,以及获取关于它们的有用信息的方法。
封装在许多其他方面帮助程序员,尤其是提高代码的可维护性和可测试性。
抽象
尽管这里有许多其他的答案将抽象定义为泛化,但我个人认为这个定义是错误的。我想说泛化实际上是一种特定类型的抽象,而不是反过来。换句话说,所有的概括都是抽象,但并非所有的抽象都一定是概括。
以下是我对抽象的看法:
你会说这个图像是一棵树吗?很有可能你会。但它真的是一棵树吗?当然不是!它是一堆像素,看起来像我们可能称之为树的东西。我们可以说它代表了一棵真实树的抽象。注意,树的一些可视化细节被省略了。此外,它不生长,不消耗水,也不产生氧气。怎么可能呢?它只是屏幕上的一堆颜色,由计算机内存中的字节表示。
这就是抽象的本质。这是一种简化事物的方法,这样它们就更容易理解。你脑子里的每一个想法都是对现实的抽象。你脑海中的树和这张图片一样都不是真正的树。
在编程中,我们可以通过创建一个Tree类来利用这一点,其中包含模拟生长、水消耗和氧气生产的方法。我们的创造将代表我们对实际树木的体验,并且只包含我们真正关心的特定模拟元素。我们使用抽象作为一种用字节和数学来表示我们经验的方式。
抽象类
编程中的抽象还允许我们考虑几个“具体”对象类型(实际存在的类型)之间的共性,并在唯一的实体中定义这些共性。例如,我们的Tree类可以继承一个抽象类Plant,它有几个属性和方法适用于我们所有类植物,但删除了那些特定于每种植物类型的属性和方法。这可以显著减少代码重复,并提高可维护性。
抽象类和普通类的实际区别在于,抽象类在概念上没有“真正的”实例。构造一个Plant对象没有意义,因为它不够具体。每一种“真正的”植物也是一种更具体的植物类型。
此外,如果我们希望程序更加实际,我们可能需要考虑Tree类本身可能过于抽象的事实。实际上,每个Tree都是一种更具体的Tree类型,因此我们可以为这些类型创建类,例如Birch、Maple等,它们继承自我们的Tree类(现在可能是抽象的)。
JVM
另一个抽象的好例子是Java虚拟机(JVM),它为Java代码的运行提供了一个虚拟或抽象的计算机。它从本质上拿走了系统中所有平台特定的组件,并提供了一个抽象的“计算机”接口,而不考虑任何特定的系统。
的区别
封装与抽象的不同之处在于,它与事物的“真实”或“准确”没有任何关系。它不会删除某些组件以使其更简单或更广泛地适用。相反,它可以隐藏某些组件来实现类似的目的。
抽象
抽象是提取所有现有和可预见实现的公共属性和字段的过程。
例如: 轿车是轿车、掀背车、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();
...
}
}
抽象和封装都是用来隐藏数据的。但是有很大的不同。
封装
封装是将数据和对数据进行操作的代码绑定或包装成一个称为Class的单元的过程。
封装在实现级别解决了问题。
在类中,可以使用私有或受保护的访问修饰符来隐藏数据。
抽象
抽象是隐藏无关细节的概念。换句话说,通过对用户隐藏不必要的细节,使复杂的系统变得简单。
抽象在设计层面解决了问题。
可以通过在Java中创建接口和抽象类来实现抽象。
在ruby中,你可以通过创建模块来实现抽象。
示例:我们使用(收集,映射,减少,排序…)方法的枚举模块与数组和ruby哈希。
推荐文章
- 什么是依赖倒置原则?为什么它很重要?
- 为什么在Python方法中需要显式地有“self”参数?
- c#中朋友的对等物是什么?
- 如何在方法中访问“静态”类变量?
- 为什么c#不提供c++风格的'friend'关键字?
- String, StringBuffer和StringBuilder
- 存储库和服务层的区别?
- DDD -实体不能直接访问存储库的规则
- 为什么STL如此严重地基于模板而不是继承?
- 如何在Objective-C中声明类级属性?
- 面向方面编程与面向对象编程
- c++中类似于java的instanceof
- 在python中遍历对象属性
- 将类代码分离为头文件和cpp文件
- 在PHP中使用getter和setter而不是函数或简单的公共字段有什么优点?