封装
封装
概念
封装(Encapsulation)
尽可能隐藏对象的内部实现细节,控制用户对对象的修改和访问权限,保障内部属性的安全。
1.1 生活中的封装

1.2 不安全的代码示例
public class Card{
public String number;
public String password;
public double banlance;
public static void main(String[] args){
Card card = new Card();
//给属性赋值
card.number = "2323234234234";
card.password = "123456";
card.banlance = -1200000.00;
//访问属性
System.out.println(card.number);
System.out.println(card.password);
System.out.println(card.banlance);
}
}
存在问题:
1.直接通过对象访问属性,无法对属性所赋的值进行合法性判断。
2.数据不安全
(一) private 修饰符
修饰符:修饰程序中的各个组件,被修饰的组件拥有不同的特点与权限。
特点:
-
private表示私有的,可以修饰属性、方法。
-
被修饰的组件只能在本类中使用,对外不可见。
例:
class MyClass{
int a;
private int b;//被private修饰,只能在本类中使用
public void ma(){}
private void mb(){}//被private修饰,只能在本类中使用
}
class TestMyClass{
public static void main(String[] args){
MyClass mc = new MyClass();
mc.a = 10;
mc.b = 20;//编译错误,无权访问
mc.ma();
mc.mb();//编译错误,无权访问
}
}
(二)私有化属性、方法[重点应用]
- 使用private对属性进行封装的案例
public class Card{
private String number;
private String password;
private double banlance;
}
class Test{
public static void main(String[] args){
Card card = new Card();
card.number= "234234252"; //编译错误,无权访问
card.password="123456"; //编译错误,无权访问
card.banlance=12320; //编译错误,无权访问
//访问属性
System.out.println(card.numbe); //编译错误,无权访问
System.out.println(card.password); //编译错误,无权访问
System.out.println(card.banlance); //编译错误,无权访问
}
}
- 不合理的过度安全
如果一个类所有的属性或方法都是私有的,那么该类的对象也没有存在的价值。
控制访问权限不是一刀切,有些情况下也需要访问属性或修改属性。
(三) 提供访问或修改私有成员的途径(get/set方法)[重点应用]
-
解决过度安全问题,合理的控制内部属性安全
-
为可访问的属性提供get方法
public 返回值类型 get属性名(){ return 属性; }注意:返回值类型和属性类型一致
方法名中属性名首字母大写 -
get方法命名规范:
以get开头,后面跟着属性名,且属性名首字符大写 :比如 name属性对应的get方法 ,getName(); -
为可修改的属性提供set方法
-
set方法命名规范:
以set开头,后面跟着属性名,且属性名首字符大写: 比如name属性对应的set方法,setName(String name);语法
public void set属性名(形参类型 参数名){ this.属性名 = 参数名; } // 形参类型与属性类型一致 // 形参名和属性名可以一致, // 方法名中的属性名首字符大写示例代码
class Card{
private String number; //卡号
private String password; //密码
private double banlance; //余额
public String getNumber(){ //获取卡号
return number;
}
public void setNumber(String number){
this.number = number;
}
public String getPassword(){ //获取密码
return password;
}
public void setPassword(String password){
this.password = password;
}
public double banlance getBanlance(){
return banlance;
}
public void setBanlance setBanlance(double banlance){
this.banlance = banlance;
}
}
-
新的访问、获取方式
访问属性或修改属性全部改用掉方法的实现,
获取属性值通过 对象.get属性名()的方式 比如 card.getNumber()
设置属性值通过 对象.set属性名() 的方式 比如 card.setNumber("23423");
示例代码
Card card = new Card(); // 通过set方法设置属性值 card.setNumber("1232323"); //设置账号 card.setPassword("123456"); //设置密码 card.setBanlance(10000.00); //设置账号余额 //通过get方法获取属性值 System.out.println(card.getNumber()); System.out.println(card.getPassword()); System.out.println(card.getBanlance());
(四)get/set方法的实际作用
-
赋值亲验证数据合法性
案例
class Card{ private String number; //卡号 private String password; //密码 private double banlance; //余额 public String getNumber(){ //获取卡号 return number; } public void setNumber(String number){ this.number = number; } public String getPassword(){ //获取密码 return password; } //设置密码 // 需求 如果密码不是8位数则跳出 public void setPassword(String password){ if(password.length()!=8) return;//如果密码不是8位数则跳出 this.password = password; } public double banlance getBanlance(){ return banlance; } public void setBanlance setBanlance(double banlance){ this.banlance = banlance; } }获取字符串中的字符个数使用: 字符串.length()
封装的意义:例如疫情期间超市管理
1. 没有封装:超市如果门口无人看守,无人管理,则无法保证客户与商品的安全。 2. 属性私有:封住超市的所有出入口,则安全过度。 3. 封装后:设置出口(get)与入口(set)在出口、入口处增加扫描仪等设备,保护客户与商品的安全。

-
封装的好处
- 没有封装:超市如果门口无人看守,无人管理,则无法保证客户与商品的安全。
- 属性私有:封住超市的所有出入口,则安全过度。
- 封装后:设置出口(get)与入口(set)在出口、入口处增加扫描仪等设备,保护客户与商品的安全。
2.设置只读属性
解决办法:对于只读的属性,只提供get方法,不提供set方法
示例
class IdCard{ //身份证
private String id; //身份证号
private String name; //姓名
public String getName(){ //获取姓名
return name;
}
public void setName(String name){ //设置姓名
this.name = name;
}
public String getId(){ //获取身份证号
return id;
}
}
3.灵活多变伪装属性
获取或设置的属性与属性不一致
示例:
class Person{ //人类
private int age; //年龄
private boolean sex;//性别
public void setAge(int age){
this.age = age;
}
public int getAge(){
return 18;//永远18岁
}
//给用户展示的性别为String类型,而实际对象中保存性别的类型为boolean类型
public void setSex(String sex){
this.sex = sex.equals("男")?true:false;
}
public boolean getSex(){
return sex;
}
}
-
私有方法更加安全,仅供内部调用的方法
案例: 用户使用电脑,开机
class Computer{
public void on(){//开机
//供电、自检
startFun();
}
private void startFun(){
//供电、自检、调整转速..
}
}
(五) 总结
1.封装的意义:尽可能隐藏对象的内部实现细节,控制用户对对象的修改和访问权限,保障内部属性的安全。
2.实现封装的方式:
- 将需要封装的属性私有化处理,即使用private进行修饰
- 对需要封装的属性提供用public修饰的get或者set方法
3.get/set方法的命名规范
get属性名():get开头,后面拼接属性名,属性首字符大写,比如getName()
set属性名(String 属性):set开头,后面拼接属性名,首字符大写, 比如setName(String name);
示例代码
class Person{
private String name; //年龄
private int age; //密码
public void setName(String name){
this.name = name;
}
public void getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
}

浙公网安备 33010602011771号