什么是封装?
这个问题在这里已经有了答案:
封装可能是OOP最容易被误解的概念。
封装不是数据隐藏!
“封装”来自“胶囊”。 它意味着把所有东西放在一起,把它们封装在一个包中,我们在这里讨论的“事物”是数据和功能。 没有封装的编程意味着处理数据的函数“浮动”在代码的某个地方,虽然它们处理数据,甚至将特定类型作为输入,但它们与数据分离。
让我举一个例子,而不关注“公共”等:如果你有一个处理复数的类,它有一个真实的和想象的部分,你可以简单地定义它:
class complex {
double real;
double imaginary;
};
使用例如C语言中使用的旧的预封装样式,为了获得这个数字的绝对值,你可以定义一个如下的函数:
double absolute(double real, double imaginary);
而这根本不会连接到课堂! 当然,你也可以定义一个将类复合体作为输入的函数,但它仍然是一个外部函数。 因此,要使用它,你必须这样做:
complex A;
A.real = 1;
A.imaginary = -3;
并获得绝对值,你将不得不打电话
absolute(A.real, A.imaginary);
相反,你可以使用封装并将数据和函数放在一起:
class complex {
double real;
double imaginary;
double absolute(); // inside the class, encapsulated into it!
};
然后获得绝对值,你只需要调用方法就好
A.absolute();
这根本不需要数据隐藏。 优点是代码更易于管理,因为您可以清楚地看到所有相关的“事物”(即数据和函数)组合在一起,因此您一眼就可以知道自己拥有什么(数据)以及可以使用哪些功能它(方法)。
没有这些信息隐藏是不可能的,因为这意味着你限制了从外部访问一些成员(私人成员),因此你必须在内部有一些方法,否则你将无法对你的数据做任何事情!
与此同时,信息隐藏有助于封装的良好使用:如果人们可以从外部访问数据,那么让其他编码人员编写自己的(未封装)代码来处理数据的风险将非常高至少会导致代码重复(即无用的努力),如果实现不完全兼容,则会导致不一致。 相反,数据隐藏意味着访问私人数据的每个人都必须使用提供的公共方法,这样每个人都是一样的。
因此,数据隐藏需要封装才有意义,同时数据隐藏也有助于封装。 他们一起工作很好,但他们不是一回事!
回到你的问题:鉴于此,定义1是错误的。 正如CommuSoft所指出的那样,2并不是一个真正的定义,这是一个经验法则。 我将补充说,关于何时使用数据隐藏而不是封装,这是一条经验法则。
在附注中,electrometro表明这可能是这个问题的重复。 我认为值得注意的是,大多数答案都是错误的,包括顶级答案,它提供了封装的例子,这实际上与封装相反。
如果你想要外部引用,这里有两篇文章:
封装不是信息隐藏
抽象,封装和信息隐藏(请注意,当他开始一个名为“ENCAPSULATION”的段落并引用了很多定义时,他只是试图显示围绕这个主题的困惑;这些定义是错误的,稍后他会解释!)
隐藏数据是关于控制。 当你隐藏数据时,你会将其隐藏起来,以免被其他程序员(包括你将来的自己)隐藏,因为他们可能会对数据做一些不正确的事情,因为他们不像你那么了解它。 所以你要仔细控制他们如何使用数据 - 在这种情况下,通过隐藏数据,限制访问和可见性。
封装不是真正的“保护所有易变的东西”的做法。 声称这是过度概括的文章,因为大多数软件开发技术是关于“保护”我们稍后可能会改变的事情。 你应该知道的是,检查容易发生变化的事情并确定你想要对其他人如何看待和使用这些事情有什么限制 - 你可以如何封装这些事情通常是一个好主意。
......同样,封装也不是真正的“将功能与数据结合在一起”的做法,因为在另一个答案要求中链接了一些文章。 适当的术语可能是模块化,或简单的旧的面向对象编程 - 有许多相关的概念。 这些技术可以实现封装,但将它们称为封装是令人困惑的,特别是对于初学者。 封装真的是关于“隐藏”数据。 (在JavaScript中,你可以将一个值与一个函数一起作为函数对象的一个属性,或者通过一个闭包来实现,它们都不使用字段,也不涉及使用类的方法/ object / prototype,都将数据和函数“放在一起”,但只有闭包会通过强加访问约束来封装数据。)
封装实际上是数据隐藏。 原因是将可能以更易于管理的方式将来改变的类似功能进行分组。
封装可能不仅仅是使用可见性修饰符来实现。
链接地址: http://www.djcxy.com/p/4107.html