封装
封装是一种信息隐藏技术,依赖于访问权限控制符实现
- 所谓封装即是,隐藏对象中属性和一些实现细节,仅对外提供公共的访问方法
- 类:是指将数据和基于数据的操作封装在一起
- 结合访问权限控制符,将数据和数据操作保护在内部
- 系统的其他部分只有通过在数据外面的被授权的操作才能够进行交互
- 目的是将类的使用者和设计者分开
- 在面向对象的编程中,用类来封装相关的数据和方法,保证了数据的安全和系统的严密性
思考:我们之前定义的类中,都没有关注访问权限控制符,会有什么问题?
- 不进行权限控制,成员可能被不应该具有访问权限的类访问到
- 普通情况的访问和修改的形式过于简陋,没有办法做任何处理
- 可能用户会设置不合法的数据
- 希望用户能够看到应该看的内容
封装具体应该怎么做?
-
应该认真考虑成员变量的访问权限,普遍来说,成员变量应该设置成private
- 然后,为了修改成员变量的值,提供public的set方法
- 为了访问成员变量的值,提供public的get方法
-
get、set方法具有严格的定义格式
- 对于变量xxx,应该使用getXxx,setXxx的名字
- 对于boolean类型的变量来说,推荐的get方法写法为isXxx,所以布尔类型变量不推荐使用isXxx的形式声明
- 使用isXxx的定义方式会和约定的get方法写法撞车
- 导致某些地方,会误以为该布尔类型变量名为xxx,导致出错
-
使用get、set方法的好处
- 私有化成员变量,隐藏实现细节
- get、set方法给私有成员变量,提供了一种访问方式
- 让使用者只能通过事先定制好的方法来访问数据
- 可以方便地加入控制的条件,限制对属性的不合理操作
- get、set方法将成员变量的读、写分离了
- 再也不是之前的读写,一体化的形式了
- 成员变量的访问从之前的不可控,变为了可控
-
静态成员变量,基本和普通成员变量没有区别,但是要注意get、set方法也要是静态的
-
封装成员变量后,给成员变量赋值的方式改变了,我们今后基本只有这种方式了
- 无参构造方法创建对象后,set方法逐一赋值
- 有参构造
- 对象名点的形式一般都是不可用的了
(1)隐藏类的实现细节;
(3)便于修改,增强代码的维护性和健壮性;
(4)提高代码的安全性和规范性;
(5)使程序更加具备稳定性和可拓展性。
题目实例:
- 创建两个类,分别用来表示长方形和正方形,同时定义所需的成员变量,代表长方形或者正方形的边长,在两个类中分别定义两个方法,用来求对应形状的面积和周长,并定义相应的get,set方法,获取和改变方形和正方形的边长。
package com.company;
public class Main {
public static void main(String[] args) {
Rectangle rectangle = new Rectangle();
rectangle.setLength(4);
rectangle.setWidth(5);
System.out.println("长方形的长为:" + rectangle.getLength() + "\t" + "长方形的宽为:"
+ rectangle.getWidth() + "\t" + "长方形的面积为:" + rectangle.getArea() + "\t" + "长方形的周长为:" + rectangle.getPerimeter() + "\t");
Square square = new Square();
square.setBorder(5);
System.out.println("正方形的边长为:" + square.getBorder() + "\t" + "正方形的面积为:" + square.getArea2() + "\t" + "正方形的周长为:" + square.getPerimeter2() + "\t");
}
}
class Rectangle {
int length;
int width;
public int getArea() {
return this.length * this.width;
}
public int getPerimeter() {
return 2 * (this.length + this.width);
}
public int getWidth() {
return width;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public void setWidth(int width) {
this.width = width;
}
}
class Square {
int border;
public void setBorder(int border) {
this.border = border;
}
public int getBorder() {
return border;
}
public int getPerimeter2() {
return 4 * (this.border);
}
public int getArea2() {
return (this.border * this.border);
}
}
输出:
长方形的长为:4 长方形的宽为:5 长方形的面积为:20 长方形的周长为:18
正方形的边长为:5 正方形的面积为:25 正方形的周长为:20