1、封装介绍
封装封装,见名知意,就是把东西包装隐藏起来,不被外界所看见,
而Java特性封装:是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,只保留一些对外接口使之与外部发生联系。系统的其他对象只能通过包裹在数据外面的已经授权的操作来与这个封装的对象进行交流和交互。也就是说用户是无需知道对象内部的细节(当然也无从知道),但可以通过该对象对外的提供的接口来访问该对象。
类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类提供的方法来对隐藏的信息向外暴露来进行操作和访问。
封装的好处(优点):
- 良好的封装能够增加内聚减少耦合。
- 通过隐藏对象的属性来保护对象内部的状态,方便修改和实现。(隐藏信息、实现细节)。
- 提高了代码的可用性和可维护性,因为对象的行为可以被单独的改变或者是扩展(将变化隔离,类内部的结构可以自由修改,增加内部实现部分的可替换性)。
- 禁止对象之间的不良交互提高模块化(良好的封装能够减少耦合)。
- 可以对成员变量进行更精确的控制。
- 容易保证类内部数据间的一致性,从而提高软件的可靠性。
提到Java的封装,那么肯定离不开四种权限修饰:
修饰符 | 同类中 | 同一个包中(子类和无关类) | 不同包(子类) | 不同包(无关类) |
public | √ | √ | √ | √ |
protected | √ | √ | √ | |
default | √ | √ | ||
private | √ |
2、封装的引入
首先我们先来看一下下面的这个Person类。
public class Person { public String name;//姓名 public int age;//年龄 public String sex;//性别 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } }
从上面的Person类可以看出,他的所有属性都是用public修饰的,这就好像你的姓名,年龄,性别都是写在脸上的,都暴露了出来,要是这个类有更多的属性,如身份证、电话号码、家庭住址这种比较私密的属性暴露在外面那就不安全了。
我们创建一个Person实例给他赋值:
Person person=new Person(); person.name="菜徐坤"; person.age=21; person.sex="woman";
如果我们哪天要修改属性的类型了,例如将age的类型修改为String类型的,如果你只有一处使用了这个还好,如果你有几十个甚至上百个这样地方,你是不是要改到崩溃。如果使用了封装,我们完全可以不需要做任何修改,只需要稍微改变下Person类的setAge()方法即可。
3、封装的使用
如果使用了封装,我们来看应该怎么操作。
public class Person { private String name;//姓名 private String age;//年龄,age数据类型改成String了 private String sex;//性别 public String getAge() { return age; } public void setAge(String age) { this.age = age; } /**省略其他getter和setter方法**/ }
使用封装之后,就不能再用Person类的实例来调用其属性了,会提示该属性是私有化的,不能调用,这样就保证了属性的隐蔽性。我们会提供属性public的getter和setter方法来对属性进行操作。
前面讲到修改age的数据类型,如果使用的封装,其他类使用的person.setAge(21)都不需要改变,只需修改Person类中数据类型和getter、setter方法即可。
如果你将年龄设置成 person.setAge(500),你会发现也可以,但是这就不和常理了,人怎么可能活500岁,使用封装我们能够轻松解决这样的问题。我们只需在setAge方法里面添加一些条件即可。
public class Person { private String name;//姓名 private int age;//年龄 private String sex;//性别 public int getAge() { return age; } public void setAge(int age) { if (age>256){ System.out.println("你输入的年龄有误!"); }else{ this.age = age; } } /** 省略其他属性的setter、getter **/ }