封装

封装

概念

封装(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 修饰符

修饰符:修饰程序中的各个组件,被修饰的组件拥有不同的特点与权限。

特点:

  1. private表示私有的,可以修饰属性、方法。

  2. 被修饰的组件只能在本类中使用,对外不可见。

    例:

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方法的实际作用

  1. 赋值亲验证数据合法性

    案例

    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)在出口、入口处增加扫描仪等设备,保护客户与商品的安全。
    

  1. 封装的好处

    1. 没有封装:超市如果门口无人看守,无人管理,则无法保证客户与商品的安全。
    2. 属性私有:封住超市的所有出入口,则安全过度。
    3. 封装后:设置出口(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;
    }
    
}
  1. 私有方法更加安全,仅供内部调用的方法

    案例: 用户使用电脑,开机

class Computer{
    public void on(){//开机
        //供电、自检
        startFun();
    }
   
    private void startFun(){
        //供电、自检、调整转速..
    }
}

(五) 总结

1.封装的意义:尽可能隐藏对象的内部实现细节,控制用户对对象的修改和访问权限,保障内部属性的安全。

2.实现封装的方式:

  1. 将需要封装的属性私有化处理,即使用private进行修饰
  2. 对需要封装的属性提供用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;
	}
 }
posted @ 2022-10-08 08:07  小牛同志  阅读(160)  评论(0)    收藏  举报