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


当前回答

简而言之:

抽象是一种帮助我们识别哪些特定信息是必要的,哪些信息应该隐藏的技术。

因此,封装是一种以隐藏对象的细节和实现细节的方式封装信息的技术。

其他回答

抽象:抽象的意思是显示功能的哪一部分。

封装:封装意味着隐藏功能的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);
    }
}

这里的大多数答案都关注于OOP,但封装开始得更早:

Every function is an encapsulation; in pseudocode: point x = { 1, 4 } point y = { 23, 42 } numeric d = distance(x, y) Here, distance encapsulates the calculation of the (Euclidean) distance between two points in a plane: it hides implementation details. This is encapsulation, pure and simple. Abstraction is the process of generalisation: taking a concrete implementation and making it applicable to different, albeit somewhat related, types of data. The classical example of abstraction is C’s qsort function to sort data: The thing about qsort is that it doesn't care about the data it sorts — in fact, it doesn’t know what data it sorts. Rather, its input type is a typeless pointer (void*) which is just C’s way of saying “I don't care about the type of data” (this is also called type erasure). The important point is that the implementation of qsort always stays the same, regardless of data type. The only thing that has to change is the compare function, which differs from data type to data type. qsort therefore expects the user to provide said compare function as a function argument.

封装和抽象是密切相关的,因此您可以认为它们确实是不可分割的。就实际而言,这可能是对的;也就是说,这里有一个不太抽象的封装:

class point {
    numeric x
    numeric y
}

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

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

T pi<T> = 3.1415926535

这是一个具有给定值(π)的泛型变量pi,声明并不关心变量的确切类型。诚然,我很难在真实的代码中找到这样的东西:抽象实际上总是使用封装。然而,上面的内容在c++(14)中确实存在,通过变量模板(=变量的通用模板);使用稍微复杂一点的语法,例如:

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

一种防止特定对象的数据被外部函数故意或意外误用的机制叫做“数据封装”。

在不包括背景细节或解释的情况下表现基本特征的行为被称为抽象

抽象和封装都是用来隐藏数据的。但是有很大的不同。

封装

封装是将数据和对数据进行操作的代码绑定或包装成一个称为Class的单元的过程。

封装在实现级别解决了问题。

在类中,可以使用私有或受保护的访问修饰符来隐藏数据。

抽象

抽象是隐藏无关细节的概念。换句话说,通过对用户隐藏不必要的细节,使复杂的系统变得简单。

抽象在设计层面解决了问题。

可以通过在Java中创建接口和抽象类来实现抽象。

在ruby中,你可以通过创建模块来实现抽象。

示例:我们使用(收集,映射,减少,排序…)方法的枚举模块与数组和ruby哈希。

另一个例子:

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

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

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

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