Java中的实际例子:封装 vs 信息隐藏 vs 抽象 vs 数据隐藏

4
我知道有很多关于这个问题的帖子,它们用实时例子解释了理论。这些面向对象编程术语非常简单,但对像我这样的初学者来说更加困惑。 但是,我在这里期望的不是定义和实时例子,而是期望在Java中获得每个概念的小代码片段。这将帮助我更好地理解封装、信息隐藏、抽象和数据隐藏。

1
信息隐藏是封装的另一种说法。以一种允许客户恶意(或者意外地)损坏对象状态的方式,给予不受信任(甚至受信任的)客户对对象状态的访问是非常糟糕的。在最大程度上,对象状态应该被隐藏起来,不向外界公开。 - scottb
2个回答

17

封装 = 信息隐藏 = 数据隐藏。 就是在执行某个任务时,不需要让其他人知道的信息。

class Bartender {
  private boolean hasBeer = false;
  public boolean willGiveBeerToDrinker(int drinkerAge) {
    return (hasBeer && (drinkerAge >= 21));
  }
}

class Drinker {
  private Bartender bartender = new Bartender();
  private int age = 18;
  public boolean willBartenderGiveMeBeer() {
    return bartender.willGiveBeerToDrinker(age);
  }
  // Drinker doesn't know how much beer Bartender has
}

抽象 = 同一接口的不同实现。

public interface Car {
  public void start();
  public void stop();
}

class HotRod implements Car {
  // implement methods
}

class BattleTank implements Car {
  // implement methods
}

class GoCart implements Car {
  // implement methods
}

这些实现都是独特的,但可以绑定在Car类型下。


当我们进行封装时,你的意思是...信息和数据隐藏也会出现在代码中。如果我错了,请纠正我。数据和信息隐藏是实现封装的一种方式,也是实现抽象的一种方式。我是对的吗? - Prashant Shilimkar
1
是的 -- 所有这些概念在面向对象编程中紧密联系在一起。封装是关于从不需要看到它的东西中隐藏程序细节。抽象是关于将相关对象之间的常见行为联系在一起。 - yamafontes
你已经使用Car接口给出了抽象化的例子。抽象化是隐藏不必要的信息并显示重要的信息。那么,在上面的类示例中,我们隐藏了什么,展示了什么?这里我有点困惑。 - Prashant Shilimkar
Interface 的整个目的是提供一种通用的方式来与 Car 层次结构中的对象交互。我给出的三个示例可能会有非常不同的实现方式,但它们仍然可以像相同类型一样使用。这个想法是隐藏实现的“引擎盖下”的细节,同时公开一个单一 API。 - yamafontes
封装不是关于隐藏程序细节,而是将所有数据成员和操作这些数据成员的方法收集到单个容器中,您可以在不进行数据隐藏的情况下实现封装,但是您无法在没有封装的情况下实现数据隐藏。 - raviraja

5
为了避免混淆: 封装 用于信息隐藏或数据隐藏。
封装意味着 自我包含。Java中的所有对象都具有一组数据和操作该数据的方法。因此,任何对象的用户都不必担心对象的工作方式。这样可以隐藏信息和其他复杂性。 示例: 任何Java对象都足以代表一个示例。 抽象:表示将事物变得更加普遍化,即,而不是创建非常特定的类,你可以创建基类或接口,然后扩展它们来获得你所需的特定类。 示例: class Animal {} class Lion extends Animal{}
因此,在Lion类中,你有一个广义的类即Animal。这代表抽象。 注意 KepaniHaole 给出的示例是完美的。 抽象示例:
public interface Animal{
    public String getType();
}

class Lion implements Animal {
    private String animalType = "WILD";

    @Override
    public String getType() {
        return this.animalType;
    }
}
class Cow implements Animal {
    private String animalType = "Domestic";

    @Override
    public String getType() {
        return this.animalType;
    }
}

在这个示例中,LionCow类实现了Animal接口。 LionCow覆盖Animal接口的getType方法。
这里,Lion和Cow是特殊情况,而Animal则更加通用。这样做提供了抽象性,因为每当你有一个Animal对象时,你都可以使用getType方法来知道它的类型,即进行了泛化处理。
现在,如果您注意到我在LionCow类中将animalType设置为私有,以便外部对象无法修改它。通过这种方式,我隐藏了不必要的信息,以免被外部对象访问。
所有外部对象所需的是getType方法来获取动物的type。这样做只向外部对象公开相关信息。

请纠正我如果我错了。数据和信息隐藏是实现封装的方法,而封装则是实现抽象的方法。我说得对吗? - Prashant Shilimkar
1
我会这样说:当我们进行封装时...信息和数据隐藏也会出现。因此,封装是实现此隐藏的一种方式,当您使事物变得普遍时,抽象化就会出现。 - me_digvijay
请您给出一个使用接口实现Java中抽象的简短例子,并解释如何隐藏未实现的信息以及如何显示已实现的信息。谢谢。 - Prashant Shilimkar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接