繁体   English   中英

如何使用封装?

[英]How to use encapsulation?

在我阅读在线电子书之后。他们说封装的好处是"A class can change the data type of a field and users of the class do not need to change any of their code." 我不明白他们在说什么。 该点的主要含义是什么? 请给一个例子吗?

让我们看一个简单的Vehicles类,它维护一个列表:

public class Vehicles {

    private ArrayList<String> vehicleNames;

    Vehicles() {
        vehicleNames = new ArrayList<String>();
    }

    public void add(String vehicleName) {
        vehicleNames.add(vehicleName);
    }
}

客户端将通过以下方式使用它:

public class Client {

    Public static void main(String []args) {
        Vehicles vehicles = new Vehicles();
        vehicles.add("Toyota");
        vehicles.add("Mazda");
    }
}

现在,如果Vehicles将其内部私有的vehicleNames字段更改为LinkedList ,则Client将不受影响。 这就是本书在谈论的内容,即由于封装,用户/客户端不需要进行任何更改即可解决类中的更改。

封装在面向对象的编程中非常重要。 使用封装,您可以向使用您的类库/ API的用户隐藏信息。

你问:“为什么我要向用户隐藏东西?” 原因很多。 一个主要原因是,有些顽皮的用户或者只是不知道API在做什么的用户可能会弄​​乱您的类和东西。 让我给你举个例子。

假设您在这里有一堂课:

public class Computer {
    public int coreCount;
}

如您所见, coreCount被声明为public 这意味着所有其他类都可以访问它。 现在想象一个顽皮的人这样做:

Computer myPC = new Computer ();
myPC.coreCount = 0;

即使是傻瓜也可以说这没有任何意义。 它也可能会影响程序的其他内容。 假设您想除以核心数量。 将会发生异常。 因此,为防止这种情况,我们应该创建setter和getter并将字段标记为private

C#版本:

public class Computer {
    private int coreCount;
    public int CoreCount {
        get {return coreCount;}
        set {
            if (value > 0)
                coreCount = value;
        }
    }
}

Java版本

public class Computer {
    private int coreCount;
    public int getCoreCount () {return coreCount;}
    public void setCoreCount (int value) {
        if (value > 0)
            coreCount = value;
}

现在,没有人可以将核心计数设置为非正值!

这是封装的示例。 说我们有一个Person类,就像这样

class Person {
  private String name;
  private String email;
  public String getName() { return this.name; }
  public String getEmail() { return this.email; }

  public void setName(String name) { this.name = name; }
  public void setEmail(String email) { this.email = email; }
}

并且在某个时候,我们决定我们需要将这些值存储为HashMap (出于某种原因或其他原因),而不是将其存储为一对字符串。

我们可以更改内部表示,而无需像这样修改Person类的公共接口。

class Person {
  HashMap<String, String> data;
  public Person() {
    this.data= new HashMap<String, String>();
  }
  public String getName() { return this.data.get("name"); }
  public String getEmail() { return this.data.get("email"); }

  public void setName(String name) { this.data.put("name", name); }
  public void setEmail(String email) { this.data.put("email", email); }
}

从客户端代码的角度来看,我们仍然可以获取和设置Strings名称和电子邮件,而无需担心其他任何事情。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM