今天的博客主题
Java面向对象 ——》Java封装
封装
隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读取和修改的访问级别。
封装可以实现对属性的数据访问限制,增加程序的安全性。
在面向对象程序设计方法中,封装是指将抽象性函式接口的实现细节部份包装、隐藏起来的方法。
封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。
要访问该类的代码和数据,必须通过严格的接口控制。
封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。
适当的封装可以让程式码更容易理解与维护,也加强了程序代码的安全性。
类、方法其实也是封装的体现。
封装的优点
1)减少耦合
2)类内部的结构可自由修改
3)对成员变量进行更精确的控制
4)隐藏一些信息和实现细节(调用者只需调用方法即可,不知道具体实现过程)
5)保证数据的安全性
6)操作简单(调用者在使用的时候,只需调用方法即可,调用者不需要再进行判断)
封装的实现
1)通过private关键字将属性私有化。
2)为每个属性提供公共的方法(getter,setter)
3)
【例】
public class Student {
// 私有的属性变量
private String name;
private int age;
// 公共的访问方法(getter setter)
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;
}
}
这样基本上就实现了一个封装。
这是一个Student类,当实例化之后就是一个对象,一个实实在在的实体,那这个类也叫实体类。
为什么要将属性设置成私有化,而不直接设置成公有的?
【举个栗子】大家都去银行存过钱哈,银行有保险柜来放钱,有个记录器,记录你存多少钱。如果这两个被设为公共的。你往保险柜放1000块钱,你往记录器记录你存了10000。那这就不好办了。还有谁也不知道你放的钱是真的还是假的。在程序上讲这样是不安全的,那现实中肯定也不行的了。
这时候有个解决方案,银行开设大厅窗口,设置成公共的对外访问。保险柜,记录器为私有的。
这时候你来存钱,存的钱有验证,你存多少我记录多少。这样一定程度上解决了上述问题对吧。
把这个引用到程序当中好处有很多,比如一个属性被设置为公共的,有十个地方引用到,需求变更,这个属性加点或减点东西,那引用的地方都需要改。那如果设置成私有的,提供一个对外访问的公共方法,需求再有变更,需要在这一个地方改一下就好了,别的引用也就一起改了。这就受你控制了。
如果真有被设置成公有的情况下该怎么使用呢?(不建议这么做)
// Student类
public class Student {
public String name;
public int age;
}
// main方法测试
public static void main(String[] args) {
Student s = new Student();
// 直接操作属性变量
s.name = "张三";
s.age = 19;
System.out.println("姓名:" + s.name + " 年龄:" + s.age);
}
输出结果:姓名:张三 年龄:19
公共的这种,如果一个位置这样用还好,那要是多个地方使用,发生变动改起来可要命了。
设置成私有的属性,使用方式
// Student类
public class Student {
public String name;
public int age;
// getter setter方法省略
...
}
// main方法测试
public static void main(String[] args) {
Student s = new Student();
// 通过set方法操作属性变量
s.setName("张三");
s.setAge(19);
System.out.println("姓名:" + s.getName() + " 年龄:" + s.getAge());
}
输出结果:姓名:张三 年龄:19
直接使用实体类所提供的set、get方法..
上面说了如果设置成公共的,一旦发生变化多少地方用那多少地方就得改。比如:
有一天发现设计的不合理,需要把int类型的age改成String类型的。
原有代码已经被很多地方引用了,如果是公有的
就需要把所有 student.age = xx 改成 student.age = "xxx"
如果当初设置成了私有的只需要把Student类里 private int age; 改成 private String age; 调整下对外所公开的set方法,如下
private int age;
改成
private String age
public void setAge(int age) {
this.age = age;
}
改成
public void setAge(int age) {
this.age = String.valueOf(age);
}
这样就把问题解决了,省很多事。这也是封装的优点里第二条:类内部结构可以自由更改。
设成公有的话,设置年龄的时候,难免会写错,如果写成了 student.age = 2000; 这完全不受你控制,再说那有学生这么大岁数的。如果是私有的就好办了,只需要在setAge方法进行逻辑验证
public void setAge(int age) {
if(age > 120){
System.out.println("ERROR:你输入的年龄不合法");
}else{
this.age = String.valueOf(age);
}
}
那这个问题就说了封装的优点里第三条:可以对成员变量进行精确的控制。
一般程序设计当中很少在set get方法中加载业务逻辑,这样会增加排查错误的难度。
获取学生的年龄,我们只需要调用 getAae() 是不是就好了。
别忘了年龄每年可都是会自动增长的。
你给别人提供学生的年龄,没有必要让别人知道你是怎么来实现学生年龄自动增长的。
你完全可以把这个自动计算学生年龄自动增长的方法给私有化,隐藏信息实现细节。
封装是面向对象三大特征之一。
也是比较容易理解的。
大白话说就是:把这个对象里的属性或者方法组合在一起,尽可能的去隐藏实现的细节。
控制用户对类的修改和访问程度。就是用 private 访问修饰符关键字。