今天的博客主题

       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 访问修饰符关键字。