抽象和封装之间的区别?

问题描述 投票:317回答:39

封装和抽象之间的确切区别是什么?

oop encapsulation abstraction
39个回答
253
投票

这里的大多数答案都集中在OOP上,但封装开始得更早:

  • 每个功能都是encapsulation;在伪代码中: point x = { 1, 4 } point y = { 23, 42 } numeric d = distance(x, y) 在这里,distance封装了平面中两点之间(欧几里德)距离的计算:它隐藏了实现细节。这是封装,纯粹而简单。
  • Abstraction是一个泛化的过程:采取具体的实现并使其适用于不同的,虽然有些相关的数据类型。经典的抽象示例是C的qsort函数来排序数据: 关于qsort的事情是,它不关心它排序的数据 - 实际上,它不知道它分类的数据。相反,它的输入类型是无类型指针(void*),它只是C的说法“我不关心数据的类型”(这也称为类型擦除)。重要的是,无论数据类型如何,qsort的实现始终保持不变。唯一需要改变的是比较功能,它不同于数据类型和数据类型。因此,qsort希望用户提供所述比较函数作为函数参数。

封装和抽象齐头并进,以至于你可以说明它们是真正不可分割的。出于实际目的,这可能是真的;那说,这是一个封装,不是一个抽象:

class point {
    numeric x
    numeric y
}

我们封装了点的坐标,但除了在逻辑上对它们进行分组之外,我们并没有实质性地将它们抽象出来。

这里是一个抽象的例子,它不是封装:

T pi<T> = 3.1415926535

这是具有给定值(π)的通用变量pi,并且声明不关心变量的确切类型。不可否认,我很难在实际代码中找到这样的东西:抽象几乎总是使用封装。但是,上述确实存在于C ++(14)中,通过variable templates(=变量的通用模板);使用稍微复杂的语法,例如:

template <typename T> constexpr T pi = T{3.1415926535};

22
投票

封装:从对象的实际用户隐藏不需要/不期望/正当的实现细节。例如

List<string> list = new List<string>();
list.Sort(); /* Here, which sorting algorithm is used and hows its 
implemented is not useful to the user who wants to perform sort, that's 
why its hidden from the user of list. */

抽象:是一种提供泛化的方式,因此是一种与广泛多样化的对象一起工作的常用方法。例如

class Aeroplane : IFlyable, IFuelable, IMachine
{ // Aeroplane's Design says:
  // Aeroplane is a flying object
  // Aeroplane can be fueled
  // Aeroplane is a Machine
}
// But the code related to Pilot, or Driver of Aeroplane is not bothered 
// about Machine or Fuel. Hence,
// pilot code:
IFlyable flyingObj = new Aeroplane();
flyingObj.Fly();
// fighter Pilot related code
IFlyable flyingObj2 = new FighterAeroplane();
flyingObj2.Fly();
// UFO related code 
IFlyable ufoObj = new UFO();
ufoObj.Fly();
// **All the 3 Above codes are genaralized using IFlyable,
// Interface Abstraction**
// Fly related code knows how to fly, irrespective of the type of 
// flying object they are.

// Similarly, Fuel related code:
// Fueling an Aeroplane
IFuelable fuelableObj = new Aeroplane();
fuelableObj.FillFuel();
// Fueling a Car
IFuelable fuelableObj2 = new Car(); // class Car : IFuelable { }
fuelableObj2.FillFuel();

// ** Fueling code does not need know what kind of vehicle it is, so far 
// as it can Fill Fuel**

13
投票

抽象和封装之间的区别。


12
投票

抽象:以简化/不同的方式呈现内容的想法,这种方式更容易理解和使用,或者与情况更相关。

考虑一个发送电子邮件的类......它使用抽象向你展示自己作为某种信使的男孩,所以你可以调用emailSender.send(邮件,收件人)。它实际上做了什么 - 选择POP3 / SMTP,调用服务器,MIME翻译等,被抽象掉了。你只看到你的使者男孩。

封装:保护和隐藏对象私有的数据和方法的想法。它更多地涉及使某些东西独立和万无一失。

以我为例。我把自己的心率从世界其他地方封装起来。因为我不希望任何其他人改变该变量,我不需要任何其他人来设置它以便我运行。它对我来说至关重要,但你不需要知道它是什么,你可能也不在乎。

环顾四周,你会发现你触摸的几乎所有内容都是抽象和封装的一个例子。例如,您的手机向您展示了能够接受您所说的话并向其他人说出的抽象 - 覆盖GSM,处理器架构,无线电频率以及您不理解或不关心的其他一百万件事。它还封装了您的某些数据,如序列号,ID号,频率等。

这一切都让世界变得更加美好:D


10
投票

抽象:仅显示必要的信息。让我们关注打开计算机的例子。用户不必知道系统仍在加载时发生了什么(该信息对用户是隐藏的)。

让我们再看一下ATM的例子。客户不需要知道机器如何读取PIN并处理交易,他只需输入PIN,拿走现金并离开。

封装:处理隐藏类的敏感数据,从而私有化其中的一部分。这是一种通过不允许从外部访问它来将某些信息保密给其客户的方法。


8
投票

另一个例子:

假设我创建了一个不可变的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_;
}

现在很明显我已经封装了宽度和高度(访问在某种程度上受限制),但我没有抽象出任何东西(好吧,也许我已经忽略了矩形在坐标空间中的位置,但这是一个缺陷例)。

良好的抽象通常意味着良好的封装。

良好抽象的一个例子是通用数据库连接类。它的公共接口是数据库无关的,非常简单,但允许我通过连接做我想做的事情。而你看到了吗?那里还有封装,因为类必须具有所有低级句柄和内部调用。


8
投票

AbstractionEncapsulation使用一个通用的例子

------------------------------------------------------------------------------------------------------------------------------------

我们都使用计算器来计算复杂的问题!


7
投票

防止特定对象的数据安全地被外部函数故意或意外滥用的机制称为“数据封装”

表示基本特征而不包括背景细节或解释的行为称为抽象


7
投票

抽象:抽象意味着显示What功能的一部分。

封装:封装意味着隐藏功能的How部分。

让我们举一个非常简单的例子

/// <summary>
/// We have an Employee class having two properties EmployeeName and EmployeeCode
/// </summary>
public class Employee
{
    public string EmplpyeeName { get; set; }
    public string EmployeeCode { get; set; }

    // Add new employee to DB is the main functionality, so are making it public so that we can expose it to external environment
    // This is ABSTRACTION
    public void AddEmployee(Employee obj)
    {
        // "Creation of DB connection" and "To check if employee exists" are internal details which we have hide from external environment
        // You can see that these methods are private, external environment just need "What" part only
        CreateDBConnection();
        CheckIfEmployeeExists();
    }


    // ENCAPLUSATION using private keyword
    private bool CheckIfEmployeeExists()
    {
        // Here we can validate if the employee already exists
        return true;
    }

    // ENCAPLUSATION using private keyword
    private void CreateDBConnection()
    {
        // Create DB connection code
    }
}

控制台应用程序的程序类

class Program
{
    static void Main(string[] args)
    {
        Employee obj = new Employee();
        obj.EmplpyeeName = "001";
        obj.EmployeeCode = "Raj";

        // We have exposed only what part of the functionality
        obj.AddEmployee(obj);
    }
}

5
投票

封装正在将复杂性包含在一个类中并因此封装......而抽象是一个与其他对象不同的对象的特征......

抽象可以通过使具有一个或多个方法抽象的类抽象来实现。这只不过是扩展它的类应该实现的特性。例如当你发明/设计汽车时,你定义了一个特征,比如汽车应该有4个门,断裂,方向盘等......所以任何使用这种设计的人都应该包括这个特性。实现不是每个抽象的头。它只会定义应包含的特征。

实现封装是通过利用访问修饰符(如公共,私有,受保护以及继承,聚合或组合)将数据和行为保持在一个类别的封装中。因此,您只展示所需的东西,也只展示您想要展示的范围。即公共,受保护,友好和私人的基础......例如GM决定使用上面提到的汽车设计。但是它们具有各种具有相同特性并且具有几乎相同功能的产品。所以他们写了一个扩展上面抽象类的类。它说明了齿轮箱应该如何工作,应该如何工作,方向盘应该如何工作。然后所有产品都使用这种通用功能。他们不需要知道齿轮箱是如何工作的,也不知道工程或转向风的工作原理。 Indivisual产品肯定有更多功能,如a / c或自动锁等......

两者都很强大;但是使用抽象需要比封装更多的技能,更大的应用程序/产品无法在不抽象的情况下生存。


5
投票

抽象---隐藏实现 - 设计 - 使用接口/抽象类

封装 - 隐藏数据 - 开发---使用访问修饰符(公共/私有)


127
投票

封装隐藏了实现细节,这些细节可能是也可能不是通用或专用行为。

抽象提供了一种概括(比如一组行为)。

这是一个很好的阅读:对象机构的Edward V. Berard的Abstraction, Encapsulation, and Information Hiding


5
投票

我们来看一个堆栈的例子。它可以使用数组或链表实现。但它支持的操作是推送和弹出。

现在抽象只暴露了push和pop接口。底层表示是隐藏的(它是一个数组还是一个链表?),并提供了一个定义良好的接口。现在,您如何确保不会对抽象数据进行意外访问?这就是封装的用武之地。例如,C ++中的类使用访问说明符来确保防止意外访问和修改。而且,通过将上述接口公之于众,它确保了操纵堆栈的唯一方法是通过定义良好的接口。在这个过程中,它已经耦合了数据和可以操作它的代码(让我们不在这里涉及友元函数)。也就是说,代码和数据被绑定在一起或绑定或封装。


4
投票

来自this

OOPS中封装和抽象的区别

抽象和封装是两个重要的面向对象编程(OOPS)概念。封装和抽象都是相互关联的术语。

封装与抽象之间的真实生活差异

封装意味着隐藏。封装也称为数据隐藏。你可以认为封装就像一个胶囊(药片),它将药物藏在里面。封装是包装,只是隐藏属性和方法。封装用于在单个单元中隐藏代码和数据,以保护数据免受外界影响。类是封装的最佳示例。

抽象是指仅向预期用户显示必要的细节。顾名思义,抽象是“任何事物的抽象形式”。我们在编程语言中使用抽象来创建抽象类。抽象类表示类的方法和属性的抽象视图。

封装和抽象之间的实现差异

  1. 使用接口和抽象类实现抽象,而使用私有和受保护的访问修饰符实现Encapsulation。
  2. OOPS通过阻止程序员以非预期的方式访问数据,利用封装来强制执行类型的完整性(即,以确保以适当的方式使用数据)。通过封装,只有预定的一组功能可以访问数据。与访问限制(公共/私有等)捆绑在一起的数据类型和操作(方法)的集合术语是一个类。

4
投票

我将尝试以一种简单的方式演示封装。让我们看看..

  • 将数据和函数包装到单个单元(称为类)中称为封装。包含和隐藏有关对象的信息的封装,例如内部数据结构和代码。

封装是 -

  • 隐藏复杂性,
  • 将数据和功能绑定在一起,
  • 使复杂方法变得私密,
  • 使实例变量的私有,
  • 隐藏最终用户不必要的数据和功能。

封装实现抽象。

和抽象是 -

  • 显示什么是必要的,
  • 数据需要从最终用户抽象,

让我们看一个例子 -

下图显示了“要添加到数据库中的客户详细信息”的GUI。

通过查看图像,我们可以说我们需要一个客户类。

第1步:我的客户类需要什么?

  • 2个变量用于存储客户代码和客户名称。
  • 1将客户代码和客户名称添加到数据库中的功能。 namespace CustomerContent {public class Customer {public string CustomerCode =“”; public string CustomerName =“”; public void ADD(){//我的数据库代码将在这里}

现在只有ADD方法不能单独在这里工作。

第2步:验证如何工作,ADD功能如何?

我们需要数据库连接代码和验证代码(额外方法)。

public bool Validate()
{
    //Granular Customer Code and Name
    return true;
}

public bool CreateDBObject()
{
    //DB Connection Code
    return true;
}


class Program
{
static void main(String[] args)
{
CustomerComponent.Customer obj = new CustomerComponent.Customer;

obj.CustomerCode = "s001";
obj.CustomerName = "Mac";

obj.Validate();
obj.CreateDBObject();

obj.ADD();
}
}

现在不需要向最终用户显示额外方法(Validate(); CreateDBObject()[复杂和额外方法])。用户只需要查看并了解将添加的客户代码,客户名称和ADD按钮记录..最终用户不关心它如何将数据添加到数据库?

步骤-3:隐藏不涉及最终用户交互的额外且复杂的方法。

因此,将那些复杂和额外的方法设为私有而不是公共(即隐藏这些方法)并删除obj.Validate(); obj.CreateDBObject();从主类课程我们实现封装。

换句话说,简化最终用户的接口是封装。

所以现在代码如下所示 -

namespace CustomerContent
{
public class Customer
{
public string CustomerCode = "";
public string CustomerName = "";
public void ADD()
{
   //my DB code will go here
}

private bool Validate()
{
    //Granular Customer Code and Name
    return true;
}

private bool CreateDBObject()
{
    //DB Connection Code
    return true;
}


class Program
{
static void main(String[] args)
{
CustomerComponent.Customer obj = new CustomerComponent.Customer;

obj.CustomerCode = "s001";

obj.CustomerName = "Mac";

obj.ADD();
}
}

摘要:

第1步:我的客户类需要什么?是抽象。

步骤-3:步骤-3:私有化不涉及最终用户交互的额外且复杂的方法是封装。

附: - 上面的代码很难,很快。


4
投票

以下段落帮助我了解它们之间的差异:

数据封装是捆绑数据的机制,使用它们和数据抽象的功能是仅暴露接口并从用户隐藏实现细节的机制。

你可以阅读更多here


3
投票

信息隐藏对于抽象或封装不是严格要求的。信息可能会被忽略,但不必隐藏。

封装是将某事物视为单一事物的能力,即使它可能由许多复杂的部分或想法组成。例如,我可以说我坐在一把“椅子”而不是指那把椅子的许多不同的部分,每个部分都有一个特定的设计和功能,所有部分都恰好合适,以便舒适地握住我的屁股几英尺远离地板。

通过封装启用抽象。因为我们封装了对象,所以我们可以将它们视为以某种方式相互关联的事物,而不是陷入内部对象结构的微妙细节中。抽象是能够考虑更大的图景,而不是关注细节。这个词的根是抽象的,如出现在学术论文顶部的摘要,而不是抽象,因为在一个只能被实例化为派生子类的类中。

我可以诚实地说,当我把我的屁股放在椅子上时,我从来没有想过那把椅子的结构会如何抓住并保持我的体重。这是一个不错的椅子,我不必担心这些细节。所以我可以将注意力转向我的电脑。而且,我不会考虑计算机的组成部分。我只是看一个代表我可以输入的文本区域的网页的一部分,我正在用语言进行交流,几乎没有考虑我的手指如何在键盘上如此快速地找到正确的字母,以及如何最终在点击这些键并发布到此论坛之间建立连接。这是抽象的强大力量。由于可以信任系统的较低级别以保持一致性和精确性,因此我们需要注意更多的工作。


2
投票
class Aeroplane : IFlyable, IFuelable, IMachine
{ // Aeroplane's Design says:
  // Aeroplane is a flying object
  // Aeroplane can be fueled
  // Aeroplane is a Machine
}
// But the code related to Pilot, or Driver of Aeroplane is not bothered 
// about Machine or Fuel. Hence,
// pilot code:
IFlyable flyingObj = new Aeroplane();
flyingObj.Fly();
// fighter Pilot related code
IFlyable flyingObj2 = new FighterAeroplane();
flyingObj2.Fly();
// UFO related code 
IFlyable ufoObj = new UFO();
ufoObj.Fly();
// **All the 3 Above codes are genaralized using IFlyable,
// Interface Abstraction**
// Fly related code knows how to fly, irrespective of the type of 
// flying object they are.

// Similarly, Fuel related code:
// Fueling an Aeroplane
IFuelable fuelableObj = new Aeroplane();
fuelableObj.FillFuel();
// Fueling a Car
IFuelable fuelableObj2 = new Car(); // class Car : IFuelable { }
fuelableObj2.FillFuel();

// ** Fueling code does not need know what kind of vehicle it is, so far 
// as it can Fill Fuel**

2
投票

抽象是隐藏用户的非有用数据,封装将数据绑定到一个封装(一个类)。我认为封装是我们实现抽象的方式。


2
投票

抽象和封装过程都会生成接口。

通过封装生成的接口隐藏了实现细节。

与抽象之前相比,通过抽象生成的接口适用于更多数据类型。


2
投票

Abstraction是我们将要实施的合同。实施可能会在一段时间内发生变化。各种实现本身可能隐藏也可能不隐藏,但在抽象背后隐藏。

假设我们在APIs中定义了一个类的所有interface,然后要求我们的代码的用户依赖于APIs定义的interface。我们可以自由地改进或修改实施,只有我们必须遵守设定的合同。用户不会与我们的实施相结合。

我们在抽象中展示所有必需规则(方法),规则的实现留给实现者实体,实现也不是抽象的一部分。它只是签名和声明是什么使抽象。

Encapsulation只是通过减少状态和行为的访问来隐藏内部细节。封装的类可能有也可能没有明确定义的Abstraction

java.util.Listjava.util.ArrayList的抽象。用java.util.ArrayList访问修饰符标记的non public的内部状态是封装。

编辑假设一个类Container.nava implements IContainerIContainer可以声明像addElementremoveElementscontains等方法。这里IContainer代表它的实现类的抽象。抽象是将类的API或模块或系统声明为外部世界。这些API成为contract。该系统可能已经或可能尚未开发。系统的用户现在可以依赖于声明的API,并确保实现此类合同的任何系统始终遵循声明的API,它们将始终为这些API提供tge实现。一旦我们编写了一些具体的实体,那么决定隐藏我们的内部状态就是封装


1
投票

我认为封装是一种实现抽象的方法。看看以下链接。

Abstraction and Encapsulation


107
投票

许多答案和他们的例子都是误导性的。

Encapsulation是将对该数据进行操作的数据和函数打包到单个组件中,并限制对某些对象组件的访问。 封装意味着对象的内部表示通常在对象定义之外的视图中隐藏。

Abstraction是一种代表基本功能而不包含实现细节的机制。

封装: - 信息隐藏。 抽象: - 实施隐藏。

例:

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对象的任何可访问成员(数据/函数)都受到限制,并且只能由该对象访问。

foo foo_obj(3, 4);
int sum = foo_obj.add();

方法add的实现是隐藏的。 - >抽象。


1
投票

简而言之

使用的抽象 - >封装和封装使用 - >数据隐藏

要么

数据隐藏是Encapsulation的一个子集,Encapsulation是Abstraction的一个子集

参考:http://www.tonymarston.co.uk/php-mysql/abstraction.txt


96
投票

封装将一些东西放在一个盒子里,然后给你一个窥视孔;这可以防止你对齿轮进行捣乱。

抽象平局忽略了无关紧要的细节,比如是否有齿轮,棘轮,飞轮或核心;他们只是“走”

封装的例子:

  • 内裤
  • 工具箱
  • 钱包
  • 手提包
  • 胶囊
  • 冷冻碳酸​​盐
  • 一个盒子,上面有或没有按钮
  • 墨西哥卷饼(技术上,墨西哥卷饼周围的玉米饼)

抽象的例子:

  • “事物组”是一种抽象(我们称之为聚合)
  • “包含其他东西的东西”是一种抽象(我们称之为构图)
  • “容器”是另一种“包含其他东西”抽象的东西;请注意,所有封装示例都是各种容器,但并非所有容器都展示/提供封装。例如,篮子是不封装其内容物的容器。

63
投票

Encapsulation意味着隐藏数据,如使用getter和setter等。

Abstraction意味着 - 使用抽象类和接口等隐藏实现。


40
投票

抽象是一般术语。即封装是抽象的子集。

例2: 解决方案架构师是创建整个解决方案的高级抽象技术设计的人,然后将此设计移交给开发团队进行实施。

在这里,解决方案架构师充当抽象,开发团队充当封装。

Courtesy


30
投票

上面提供了很多好的答案,但我将在这里提出我的(Java)观点。

数据封装只是意味着包装和控制类中逻辑分组数据的访问。它通常与另一个关键字 - 数据隐藏相关联。这是使用access modifiers在Java中实现的。

一个简单的例子是定义一个私有变量,并使用getter和setter方法提供对它的访问,或者将一个方法设为私有,因为它只使用该类。用户无需了解这些方法和变量。

注意:不应该误解封装只是关于数据隐藏。当我们说封装时,重点应放在分组或打包或捆绑相关数据和行为上。

另一方面,数据抽象是概括的概念,因此下面的复杂逻辑不会暴露给用户。在Java中,这是通过使用interfacesabstract类来实现的。

示例 -

假设我们有一个接口Animal,它有一个函数makeSound()。有两个具体的类Dog和Cat实现了这个接口。这些具体类具有makeSound()函数的单独实现。现在让我们说我们有一只动物(我们从一些外部模块得到这个)。所有用户都知道它接收的对象是动物,用户有责任打印动物声音。一种强制方式是检查收到的对象以识别它的类型,然后将其类型化为该Animal类型,然后在其上调用makeSound()。但更简洁的方法是将事物抽象出来。使用Animal作为多态参考并在其上调用makeSound()。在运行时,取决于真实的Object类型是什么,将调用适当的函数。

更多细节here

复杂逻辑位于电路板中,封装在触摸板中,并提供了一个漂亮的界面(按钮)以将其抽象给用户。

PS:以上链接是我个人的博客。


29
投票
  • 通过抽象,您可以专注于对象的作用而不是对象的作用
  • 封装意味着隐藏对象如何做某事的内部细节或机制。

就像你开车时一样,你知道油门踏板的功能,但你可能不知道它背后的过程,因为它是封装的。

让我举一个C#的例子。假设你有一个整数:

int Number = 5;
string aStrNumber = Number.ToString();

您可以使用Number.ToString()之类的方法返回数字5的字符表示形式,并将其存储在字符串对象中。该方法告诉您它的作用而不是它是如何做的。


25
投票

这些有些模糊的概念并非计算机科学和编程所独有。我想提供一些额外的想法,可以帮助其他人理解这些重要的概念。


Short Answer

封装 - 隐藏和/或限制对系统某些部分的访问,同时暴露必要的接口。

抽象 - 除了具体的现实,特定的对象或实际的实例之外,考虑去除某些特征的东西,从而降低复杂性。

主要的相似之处在于这些技术旨在提高理解力和实用性。

主要区别在于抽象是一种更简单地表示事物的方法(通常是为了使表示更广泛适用),而封装是一种改变其他事物与某事物相互作用的方法。


Long Answer

Encapsulation

这是一个封装的例子,希望能让事情变得更清晰:

在这里,我们有一个Arduino Uno,以及一个机箱内的Arduino Uno。封装是封装的全部代表。

封装旨在保护某些组件免受外部影响和知识的影响,以及暴露其他东西应该与之交互的组件。在编程术语中,这涉及information hiding虽然access modifiers,它改变了可以读取和写入某些变量和/或属性的程度。

但除此之外,封装还旨在更有效地提供这些外部接口。使用我们的Arduino示例,这可能包括漂亮的按钮和屏幕,这使得用户与设备的交互更加简单。它们为用户提供了影响设备行为的简单方法,并获得有关其操作的有用信息,否则将更加困难。

在编程中,这涉及将各种组件分组为可分离的构造,例如functionclassobject。它还包括提供与这些结构交互的方法,以及获取有关它们的有用信息的方法。

封装以许多其他方式帮助程序员,尤其是改进的代码可维护性和可测试性。

Abstraction

虽然这里的许多其他答案都将抽象定义为概括,但我个人认为该定义是错误的。我会说泛化实际上是一种特定的抽象类型,而不是相反。换句话说,所有概括都是抽象,但所有抽象都不一定是概括。

这就是我喜欢抽象的方式:

你会说那里有一棵树吗?你有可能。但它真的是一棵树吗?好吧,当然不是!它是一堆看起来像我们可能称之为树的像素。我们可以说它代表了一棵真树的抽象。请注意,省略了树的几个可视细节。此外,它不会生长,消耗水或产生氧气。怎么可能呢?它只是屏幕上的一堆颜色,由计算机内存中的字节表示。

这是抽象的本质。这是一种简化事物的方式,因此更容易理解。贯穿始终的每一个想法都是对现实的抽象。你的树的心理形象不再是这个jpeg的实际树。

在编程中,我们可以通过使用模拟生长,耗水和氧气生成的方法创建Tree类来利用它。我们的创作将代表我们对实际树木的体验,并且仅包括我们真正关心的特定模拟元素。我们使用抽象作为表示我们对字节和数学的经验的一种方式。

Abstract Classes

编程中的抽象还允许我们考虑几个“具体”对象类型(实际存在的类型)之间的共性,并在唯一实体中定义这些共性。例如,我们的Tree类可能继承自abstract class Plant,它具有适用于我们所有类植物类的若干属性和方法,但删除了对每种植物类型特定的属性和方法。这可以显着减少代码重复,并提高可维护性。

abstract class和普通class的实际区别在于概念上没有abstract class的“真实”实例。构造一个Plant对象是没有意义的,因为这不够具体。每个“真正的”Plant也是更具体的Plant类型。

此外,如果我们希望我们的程序更加真实,我们可能要考虑这样一个事实,即我们的Tree类本身可能过于抽象。实际上,每个Tree都是更具体的Tree类型,因此我们可以为BirchMaple等类型创建类,这些类继承自我们的,现在可能是abstractTree类。

JVM

另一个很好的抽象示例是Java Virtual Machine (JVM),它为运行的Java代码提供了一个虚拟或抽象的计算机。它基本上剥夺了系统的所有平台特定组件,并提供了“计算机”的抽象接口,而不考虑任何系统。

The Difference

封装与抽象的不同之处在于它与“真实”或“准确”某些东西没有任何关系。它不会删除某些内容的组件,以使其更简单或更广泛适用。相反,它可能隐藏某些组件以实现类似的目的。

© www.soinside.com 2019 - 2024. All rights reserved.