C# 中数据隐藏和封装之间的区别?

Difference between Data hiding & Encapsulation in C#?

我一直在浏览一些博客文章和 Whosebug 答案,以了解如何在 C# 中实现封装 (Encapsulation in C# - .NET tutorials and Encapsulation in C# - JavaTPoint)。所有这些博客文章和答案都按预期定义了封装。

Binding data and methods togeather in a type is called encapsulation

但是,在实现部分,他们说它是在 C# 中通过定义私有变量并使用访问器和修改器/属性提供对它们的访问来实现的。我的问题是这不是数据隐藏吗?为什么它被认为是封装?此外,类、结构(类型)等不应该是在 C# 中实现封装的方式,因为在这些中我们将数据字段和功能绑定在一起。

@Unmesh Kondolikar 对这个问题的回答非常清晰here

Encapsulation is programming language feature which enables data hiding. However note that you can do data\information hiding even without encapsulation. For example using modules or functions in non Object Oriented programming languages. Thus encapsulation is not data hiding but only a means of achieving it.

术语信息隐藏和封装之间的使用存在一些歧义。(refer here.) 总之,封装是指将相关实体(属性和功能)分组到一个单元中,以后可以用单个名称引用。例如在过程编程中,将重复代码分组到过程中可以被认为是封装。设计者可以使用通用名称来引用此类过程。在 OOP 中,这个概念从子例程扩展到 classes 和结构。 任何 class 定义 public 实例变量仍然被封装(虽然,这是一个糟糕的设计选择),但它没有实现数据隐藏。

未实现数据隐藏的封装代码在我们尝试对其进行更改时可能会出现以下问题。作为信息 hiding/encapsulation 的示例,请考虑以下 class:(source)

public class BankAccount {
    public int dollars;
}

这个class的实现是封装的,但是仍然不够灵活(比如以后我们不能轻易增加对个别美分的支持)和不安全(比如账户可以变成负数)。但是,如果我们将数据隐藏在正式定义的方法接口后面,我们将获得灵活性和安全性。

public class BankAccount {
    private int dollars;

    public void deposit(int dollars) {
        this.dollars += Math.max(0, dollars);
    }
}

我们现在可以控制状态的修改方式,我们还可以在不破坏客户端代码的情况下更改实现:

public class BankAccount {
    private int cents;

    public void deposit(int dollars) {
        deposit(dollars, 0);
    }

    public void deposit(int dollars, int cents) {
        this.cents += Math.max(0, 100 * dollars) + Math.max(0, cents);
    }
}

class 现在封装得更好,因为我们隐藏了有关其底层实现的信息。