2012-08-15 60 views
68

可能重复:
Abstraction VS Information Hiding VS Encapsulation抽象VS封装在Java中

我知道这个问题可能已经问上千次在这个论坛上,甚至网也充满了很多的定义有关这些概念,但都听起来相同,都使用相同的技术词汇。例如下面的定义

封装是一个绑定或包装数据和操作数据代码到一个单一的实体的过程。这使得数据不受外部接口和误用的影响。考虑封装的一种方法是作为一种保护性包装,防止代码和数据被包装外定义的其他代码任意访问。

我从上面的定义了解到,创建变量时,将它们标记为private,并为这些变量生成getter-setter,并使用object访问这些getter和setter。这样数据就隐藏在对象内部,只能通过对象访问。 希望我是对的


抽象是抽象的Java中的工艺被用来隐藏某些细节,只显示对象的基本特征。换句话说,它处理对象(接口)的外部视图。

现在这是我永远困惑的部分。每当我想到抽象时,我想到的东西就是Abstract类(可能是因为两者都有Abstract关键字)。上面的定义说抽象意味着隐藏数据,只显示需要的细节,但这正是我们已经在封装中做的权利?那么有什么区别。我也没有得到中对象的侧视图,它涉及对象的外部视图。

有人可以请一些现实生活中的例子或一些程序化的例子,如果可能的话更多的光线。

回答

30

抽象是关于识别共同点并减少您必须在代码的不同级别上使用的功能。

例如我可能有一个Vehicle班。 A Car将衍生自Vehicle,以及Motorbike。我可以询问每个Vehicle轮子,乘客等的数量,并且该信息已被抽象并且从CarsMotorbikes被识别为共同的。

在我的代码,我可以经常只是通过普通的方法go()stop()等。当我后来添加一个新的车辆类型(例如Scooter)我的大部分代码将继续无视这一事实,并实施应对VehiclesScooter单独担心Scooter的特殊性。

65

OO Abstraction中一流水平的设计时,用的客观隐藏实现复杂的如何的由API /设计/系统提供的功能得以实施,在一定意义上简化了“接口”来访问基础实施。

该处理可以在抽象,这使得大的系统,而不增加的代码和理解,在复杂性更高的层,以建立的日益“更高”水平(层)被重复。例如,Java开发人员可以利用FileInputStream的高级功能,而不必关心其工作原理(即文件句柄,文件系统安全检查,内存分配和缓冲将在内部管理,并且对消费者隐藏)。这允许更改FileInputStream的实现,并且只要API(接口)与FileInputStream保持一致,则针对先前版本构建的代码仍然可以工作。

同样,设计你的类时,你会想从别人隐藏内部实现尽可能。

在Booch的定义,OO封装通过Information Hiding实现,并且特别是围绕隐藏内部数据(场/代表状态成员)的一类实例拥有,通过强制执行在访问内部数据以及防止对这些领域进行直接的,外部的改变,以及隐藏课程的任何内部实现方法(例如,通过使它们变得私密)。

例如,类字段可以由默认private,且仅当被要求这些外部访问,将一个get()和/或set()(或Property)从类露出。 (在现代OO语言中,字段可被标记为readonly/final/immutable,其甚至在班级内进一步限制变化)。

实施例,其中NO信息隐藏已经应用(不好的做法)

class Foo { 
    // BAD - NOT Encapsulated - code external to the class can change this field directly 
    // Class Foo has no control over the range of values which could be set. 
    public int notEncapsulated; 
} 

实施例,其中场封装已经施加:不可改变/ constructor-的

class Bar { 
    // Improvement - access restricted only to this class 
    private int encapsulated; 

    // The state of Bar (and its fields) can now be changed in a controlled manner 
    public void setEncapsulatedField(int newValue) { 
     if (newValue < 100) { 
      encapsulated = newValue; 
     } 
     // else throw ... out of range 
    } 
} 

实施例只有初始化一个字段

class Baz { 
    private final int onlyValue; 

    public void Baz(int immutableValue) { 
     // ... can check that immutableValue is valid 
     onlyValue = immutableValue; 
    } 
    // Further change of `onlyValue` outside of the constructor is NOT permitted 
    // even within the same class 
} 

重新:抽象VS抽象类

Abstract classes是促进类之间的共同性的重用类,但其本身不能直接与new()被实例化 - 抽象类必须被继承,并且仅concrete(非抽象)子类可能被实例化。 Abstractionabstract class之间可能存在的一个混淆之处在于,在OO的早期,继承被更多地用于实现代码重用(例如,具有关联的抽象基类)。如今,composition is generally favoured over inheritance,并且有可用来实现抽象更多的工具,如通过接口,事件/代表/功能,特性/混入等

回复:封装VS信息隐藏

最近encapsulation是当确定哪些方法,字段,属性,事件等到bundle成为一个类时,通常也以更一般的意义使用。

引用百科:

在面向对象的编程语言的更多的具体设置中,概念用来表示任一种信息隐藏机构,捆扎机构,或两者的组合。

例如,在声明中“我已经封装了数据访问代码到自己的类”封装的解释大致相当于Separation of Concerns本金(在S固体),和可以被认为是重构的同义词。


[1] 一旦你已经看到了Booch的encapsulation cat picture你永远无法忘记的封装 - 面向对象的分析与应用设计的P46, 第二版

+0

所以我们使用的Java API是一个抽象? – sras 2015-07-23 06:58:12

+0

是的,从较高层面来说,API确实为消费者提供了一种更简单的抽象方式,它完全没有意识到其内部设计背后的潜在复杂性。 Java显然是一种语言,具有许多相关的高级框架。然而,我更具体地相信,在OO设计[主要术语](https://en.wikipedia.org/wiki/Object-oriented_design)被创造出来之前,抽象更具体地指的是类级设计和分解而不是指框架或企业级设计。 – StuartLC 2015-07-23 07:23:34

40

简单单词: 您在决定执行什么时做抽象。 你在隐藏你已经实现的东西时进行封装。