封装和抽象概念之间的区别

时间:2010-07-29 12:19:15

标签: oop encapsulation abstraction

  

可能重复:
  Abstraction VS Information Hiding VS Encapsulation

有人可以向我解释面向对象编程中的封装和抽象原则之间的主要区别(如果可能的话,还有示例)。

4 个答案:

答案 0 :(得分:6)

样品:

// NO ABSTRACTION, NO ENCAPSULATION
const int catLegs = 4;
const int spiderLegs = 8;

Leg[] catLegs;
Leg[] spiderLegs;

void MakeCatRun(Distance b) { for (int i=0; i<catLegs; ++i) catLegs[i] += b; }
void MakeSpiderRun(Distance b) { for (int i=0; i<spiderLegs; ++i) spiderLegs[i] += b; }

封装:

// ENCAPSULATION
class Cat
{
    Leg[] legs;
    int nLegs;

    public void Run(Distance b) { for (int i=0; i < nLegs; ++i) leg[i] += b; }
}

class Spider
{
    Leg[] legs;
    int nLegs;

    public void Run(Distance b) { for (int i=0; i < nLegs; ++i) leg[i] += b; }
}

抽象:

 // ABSTRACTION
    class LivingBeing
    {
        Leg[] legs;
        int nLegs;

        public void Run(Distance b) { for (int i=0; i < nLegs; ++i) leg[i] += b; }
    }

    class Cat: LivingBeing       {        }

    class Spider: LivingBeing   {    }

答案 1 :(得分:5)

抽象是我们对不必要的内部机制(实现)不感兴趣的质量,可以处理系统/对象,查看基本要素。

例如:在汽车上施加制动时,您根本不在乎是否有空气制动或液压制动。抽象在这里以踏板推动的形式出现。

封装是通过在容器中打包(封装)实现细节来实现上述(抽象)的方法(从您的视力或物理接触中隐藏破坏机制和微小组件,在上述情况下)

因此,封装实际上提供了抽象!

如果环顾四周,你可以在现实世界的任何地方看到它。编程中也有它 - 如果有人为你提供了一个排序整数列表的类,你真的不需要打扰它使用的排序算法(冒泡排序/快速排序),抽象使你有可能通过方法的整数列表;就是这样。

 class Sorter
 {
  public List<Integer> Sort(List<Integer>)//Only this method is seen outside
  {
    String pattrenName=this.AdvancedPatternFinder();
    this.Advancedsorter(pattenName);
    //Return sorted list
  } 
  private String AdvancedPatternFinder(){}//NOT seen from outside
  private void Advancedsorter(String pattrenName){}//NOT seen from outside
 }

请参阅下面的动画,了解如何通过封装内部细节来提供整洁的抽象!

图片礼貌:this blog

enter image description here

答案 2 :(得分:4)

封装意味着对象的内部状态(数据)只能通过其公共方法(公共接口)进行修改:

class Encapsulated  {
  private int data;

  public int getData()  { return data; }
  public void setData(int d) { data = d; }
}

抽象意味着您可以从具体实现中抽象出来,例如:

abstract class Container  {
  int getSize();
}

class LinkedList extends Container {
  int getSize() { /* return the size */ }
}

class Vector extends Container {
  int getSize()  { /* ... */ }
}

如果您将在所有代码中使用Container抽象类而不是Vector或LinkedList,那么您将能够在不更改任何代码的情况下切换Container的具体实现(在本例中为Vector / LinkedList),从而抽象你自己来自实施。

答案 3 :(得分:1)

这两个概念是截然不同的,但密切相关,并且经常在一起。

抽象隐藏了非必要的细节,通常称为实施细节。例如,要从流中读取数据,大多数环境都具有InputStream的概念。它提供了一个ReadBytes()方法来从流中获取更多字节。它是如何被抽象掉的 - 它可以是从文件中读取,使用OS文件API,或从套接字读取,从SSH或任何其他可以作为字节流呈现的内容。 InputStream类被认为是一个抽象。

InputStream的每个实现都编码如何读取字节。例如,FileInputStream从文件中读取字节,并将当前偏移量作为私有数据成员保存到文件中。类外部的代码没有直接读取或写入此变量的自由访问权限 - 这样做可能会导致错误的结果,例如跳过部分流或重新读取。这在多线程场景中尤为重要,因为需要仔细控制对变量的更改。该类不使用自由访问权限,而是在内部使用offset(通过声明它private),并仅为外部代码提供间接访问权限,例如通过方法GetCurrentOffset()和方法{{ 1}}。然后由FileInputStream类封装offset变量。