一、介绍
封装(Encapsulation)是面向对象方法的重要原则,就是把对象的属性和操作(或服务)结合为一个独立的整体,并尽可能隐藏对象的内部实现细节。封装是把过程和数据包围起来,对数据的访问只能通过已定义的接口。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。
封装是一种信息隐藏技术,在java中通过关键字private,protected和public实现封装。什么是封装?封装把对象的所有组成部分组合在一起,封装定义程序如何引用对象的数据,封装实际上使用方法将类的数据隐藏起来,控制用户对类的修改和访问数据的程度。 适当的封装可以让程式码更容易理解和维护,也加强了程式码的安全性。
比如一部电脑主机,他就是封装起来,你可以通过一些方法改变他里面的状态,而又不需要了解他的原理,比如我按下开机键,我会知道我按下这个键,电脑就会启动,而不需要了解他怎么运行。
二、知识点介绍
1、封装的优点
2、实现封装的步骤
3、封装的作用
三、上课对应视频的说明文档
1、封装的优点
(1)良好的封装能够减少耦合。
(2)类内部的结构可以自由修改。
(3)可以对成员变量进行更精确的控制。
(4)隐藏信息,实现细节。
分析:
主要体现在信息隐藏
① 类的成员变量可以成为只读或者只写的。
比如用:访问器getXxxx();或者修改器setXxxx();
② 类可以对储存在其中的成员变量中的内容有一个整体的控制。
可以根据访问修饰符的提点在其它类中调用该类中的属性和行为。
③类的用户不需要知道类是如何储存数据的。
比如:这是一个类中得到生日的方法
public String getBirthday(){
return year + "-" + month + "-" + day;
}
public void setBirthday(String birthday){
//拆分字符串,分别取出年月日,给year、month、day进行赋值
}
而在外部调用这个方法的时候
this.getBirthday();
this.setBirthday("1990-9-9");
此时就体现出外部是不知道如何储存birthday这个方法的,用户只能调用它。
2、实现封装的步骤
(1)修改属性的可见性来限制对属性的访问(一般限制为private)
public class Person {
private String name;
private int age;
}
这段代码中,将 name 和 age 属性设置为私有的,只能本类才能访问,其他类都访问不了,如此就对信息进行了隐藏。
(2)对每个值属性提供对外的公共方法访问,也就是创建一对赋取值方法,用于对私有属性的访问
public class Person{
private String name;
private int age;
public int getAge(){
return age;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public void setName(String name){
this.name = name;
}
}
如上例 :我们将name,age属性私有化,那么除了Person这个类以外其他地方都不能使用他,所有这个时候,我们选择了全局的set,get方法,来为我们的属性name,age来存放值和取值。
采用 this 关键字是为了解决实例变量(private String name)和局部变量(setName(String name)中的name变量)之间发生的同名的冲突。
封装案例:
public class EncapTest{
private String name;
private String idNum;
private int age;
//声明set,get方法初始化与获取
public int getAge(){
return age;
}
public String getName(){
return name;
}
public String getIdNum(){
return idNum;
}
public void setAge( int newAge){
age = newAge;
}
public void setName(String newName){
name = newName;
}
public void setIdNum( String newId){
idNum = newId;
}
}
public class RunEncap{
public static void main(String args[]){
EncapTest encap = new EncapTest();
//创建对象,通过对应的set方法,初始化
encap.setName("James");
encap.setAge(20);
encap.setIdNum("12343ms");
System.out.print("Name : " + encap.getName()+ " Age : "+ encap.getAge());
}
}
如上例 ,我们在调用我们的属性name,age的时候,使用了,set,get方法,那么这就是一个典型的封装。
3、封装的作用
对象的数据封装特性彻底消除了传统结构方法中数据与操作分离所带来的种种问题,提高了程序的可复用性和可维护性,降低了程序员保持数据与操作内容的负担。
对象的数据封装特性还可以把对象的私有数据和公共数据分离开,保护了私有数据,减少了可能的模块间干扰,达到降低程序复杂性、提高可控性的目的。
案例:
描述一个计算器类
class Calculator
{
// 1. 查看具体的计算器对象抽取所有计算器具有的共同属性
public String name = "我的计算器我做主";
public double num1;
public double num2;
public char option;
// 2. 查看具体的计算器对象抽取所有计算器具有的共同功能
// 2.1 定义接受数据的功能函数
public void init( double a , char op , double b ){
num1 = a;
option = op;
num2 = b;
}
// 2.2 定义计算的功能
public void calculate(){
switch ( option )
{
case '+': System.out.println( name + " : " + num1 + " + " + num2 + " = " + ( num1 + num2 ) );
break;
case '-': System.out.println( name + " : " + num1 + " - " + num2 + " = " + ( num1 - num2 ) );
break;
case '*': System.out.println( name + " : " + num1 + " * " + num2 + " = " + ( num1 * num2 ) );
break;
case '/': {
if( num2 != 0 )
System.out.println( name + " : " + num1 + " / " + num2 + " = " + ( num1 / num2 ) );
else
System.out.println("除数不能为0!");
break;
}
case '%': {
// 1.处理结果的符号问题,使得结果的符号满足数学的要求
// 2.解决NaN的问题
System.out.println( name + " : " + num1 + " % " + num2 + " = " + ( num1 % num2 ) );
break;
}
default : System.out.println("你在捣乱,我不理你,气死你......");
}
}
}
class Demo9
{
public static void main(String[] args)
{
Calculator cal = new Calculator();
cal.init( 41 , '%' , 0 );
cal.calculate();
System.out.println("计算完毕!再来一次......");
}
}
如上例:我们声明了一个计算器的类Calculator,在里面定义了四个属性,name(计算器名字),num1(数字1),num2(数字2),option(算法),通过构造函数对num1,num2,option进行初始化,在计算器中声明一个方法calculate,在方法中我们可以通过option来确定我们的+ - * / % 的运算功能