函数是封装的一个例子吗?

时间:2009-02-10 19:58:56

标签: oop object methods encapsulation

通过将功能集成到一个函数中,是否仅仅构成了封装示例,还是需要使用对象进行封装?

我正在尝试理解封装的概念。如果我从这样的事情出发,我的想法是:

n = n + 1

作为大量代码的一部分在野外执行然后我把它放在一个像这样的函数中,然后我在一个方法中封装了这个加法逻辑:

addOne(n)
    n = n + 1
    return n

或者更多的情况是,如果我从外部世界隐藏addOne的细节,它只是封装 - 就像它是一个对象方法,我使用私有/受保护的访问修饰符?

12 个答案:

答案 0 :(得分:16)

我将是第一个不同意似乎是答案趋势的人。是的,一个函数封装了一些实现。你不需要一个对象(我认为你用它来表示一个类)。

另见Meyers

答案 1 :(得分:12)

也许你将抽象与封装混淆,后者在面向对象的更广泛的背景下被理解。

封装正确包括以下所有三个:

  • 抽象
  • 实施隐藏
  • 责任分工

抽象只是封装的一个组成部分。在您的示例中,您已经从它曾经驻留的代码主体中抽象出了添加功能。您可以通过识别代码中的某些共性 - 在特定情况下识别概念(添加)(将第一个添加到变量n)来实现此目的。由于这种能力,抽象使封装的组件 - 方法或对象 - 可重用。

封装概念同样重要的是实现隐藏的想法。这就是在面向对象领域中讨论封装的原因。实现隐藏保护对象免受其用户的影响,反之亦然。在OO中,您可以通过向对象的用户提供公共方法的接口来实现此目的,而对象的实现则在私有方法中进行。

这有两个好处。首先,通过限制对对象的访问,可以避免对象的用户将对象置于无效状态的情况。其次,从用户的角度来看,当他们使用您的对象时,他们只是松散地耦合到它 - 如果您稍后更改您的实现,它们不会受到影响。

最后,在OO设计的更广泛的背景下,责任划分是必须考虑的,以正确地解决封装问题。封装随机函数集是没有用的 - 责任需要干净地和逻辑地定义,以便尽可能少地重叠或模糊。例如,如果我们有一个Toilet对象,我们将希望从Kitchen对象中隔离其职责范围。

但是,在有限的意义上,你是正确的,一个函数,比方说,通过抽象来“模块化”一些功能。但是,正如我所说,“封装”作为一个术语,在更广泛的面向对象的背景下被理解为适用于符合上述三个标准的模块化形式。

答案 2 :(得分:6)

当然可以。

例如,仅对其参数进行操作的方法将被视为“更好地封装”,而不是对全局静态数据进行操作的方法。

封装在OOP之前很久就存在了:)

答案 3 :(得分:3)

方法不再是封装的例子,而是汽车是良好驾驶的一个例子。封装不是关于synax,它是一个逻辑设计问题。对象和方法都可以表现出好的和坏的封装。

考虑它的最简单方法是代码是否隐藏/抽象代码的其他部分的细节,这些部分不需要知道/关心实现。

回到汽车示例: 自动变速箱提供良好的封装:作为驾驶员,您关心前进/后退和速度。 手动变速箱是不好的封装:从驾驶员的角度来看,低速/高速所需的特定档位通常与驾驶员的意图无关。

答案 4 :(得分:3)

不,对象不是必需的用于封装。从最广泛的意义上讲,“封装”仅仅意味着“隐藏视图中的细节”,在这方面,一种方法正在封装其实现细节。

这并不意味着你可以出去说你的代码设计得很好,只是因为你把它分成了方法。由500个公共方法组成的程序并不比在一个1000行方法中实现的相同程序好得多。

在构建程序时,无论您是否使用面向对象技术,您都需要考虑在许多不同位置进行封装:隐藏方法的实现细节,从不需要的代码隐藏数据了解它,简化模块的接口等。

更新:为了回答您更新的问题,“将代码放入方法”和“使用访问修饰符”都是封装逻辑的不同方法,但每个方法都处于不同的级别。< / p>

将代码放在方法中会隐藏构成该方法的各行代码,以便调用者不需要关心这些行是什么;他们只担心方法的签名。

将类上的方法标记为(例如)“private”会隐藏该方法,以便的使用者不必担心它;他们只担心你班级的公共方法(或属性)。

答案 5 :(得分:1)

这是一个组件级别的事情

检查this

  

在计算机科学中,封装是将软件组件的内部机制和数据结构隐藏在定义的接口后面,这样组件的用户(其他软件)只需要知道组件的作用,并不能使自己依赖于它是如何做到的细节。目的是实现变更的潜力:可以在不影响其他组件的情况下改进组件的内部机制,或者可以使用支持相同公共接口的不同组件替换组件。

(我不太明白你的问题,如果这个链接不能解决你的疑问,请告诉我)

答案 6 :(得分:1)

封装的抽象概念意味着您隐藏实现细节。面向对象只是使用ecnapsulation的一个例子。另一个例子是名为module-2的语言,它使用(或使用)实现模块和定义模块。定义模块隐藏了实际的实现,因此提供了封装。

当你可以考虑使用黑盒子时,会使用封装。物体是一个黑盒子。您知道它们提供的方法,但不了解它们的实现方式。

[编辑] 至于更新问题中的示例:它取决于您定义封装的范围有多窄。您的AddOne示例不会隐藏我认为的任何内容。如果您的变量是一个数组索引并且您将调用方法moveNext并且可能具有另一个函数setValue和getValue,那么它将是信息隐藏/封装。这将允许人们(可能与其他一些函数一起)导航您的结构和设置并获取变量,让他们知道您使用数组。如果编程语言支持其他或更丰富的概念,您可以通过更改含义和界面来更改moveNext,setValue和getValue的实现。对我来说就是封装。

答案 7 :(得分:1)

让我们通过类比来简化这一点:你转动汽车的钥匙然后启动。你知道它不仅仅是密钥,还有 来了解正在进行的。对你来说,关键转弯=电机启动。钥匙的接口(即,例如,功能调用)隐藏了旋转发动机等的起动机马达的实施方式(实施方式)。 那是封装。你不必知道引擎盖下发生了什么,你很高兴。

如果您创建了一个人工手,比如说,为您转动钥匙,那就是封装。你正在使用额外的中间人,而不隐藏任何东西。这就是你的例子让我想起的 - 它不是封装实现细节,即使两者都是通过函数调用完成的。在这个例子中,任何人拿起你的代码都不会感谢你。事实上,他们更有可能用你的假手给你打电话。

您可以想到隐藏信息(类,函数,动态库,宏)的任何方法都可以用于封装。

答案 8 :(得分:1)

封装是一个过程,其中对象的属性(数据成员)和行为(成员函数)组合在一起作为单个实体引用为类。

答案 9 :(得分:0)

答案 10 :(得分:0)

在严格的面向对象的术语中,人们可能会想要拒绝,“纯粹”的功能不足以被称为封装......但in the real world显而易见的答案是“是的,函数封装一些代码“。

对于亵渎这种亵渎的OO纯粹主义者,考虑一个没有状态和单一方法的静态匿名类;如果AddOne()函数不是封装,那么这个类也不是!

只是为了迂腐,封装是一种抽象形式,反之亦然。 ; - )

答案 11 :(得分:-1)

在没有引用属性而不是单独方法的情况下谈论封装通常没有意义 - 当然,你可以对方法设置访问控制,但是很难看出它将如何成为其他比没有任何数据作用于封装方法的无意义。可能你可以做一些论证验证它,但我怀疑它会曲折。

所以不,你很可能不是因为你把一个方法放在一个类中而不是将它作为一个全局函数而使用封装。