封装
在面向对象程式设计方法中,封装
Encapsulation
是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。
- 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问
- 反射机制
- 要访问该类的代码和数据,必须通过严格的接口控制。
- 封装最主要的功能在于能修改自己的实现代码,而不用修改那些调用代码的程序片段
- 适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。
//第一步是确定研究的目标对象---可以区分的独立个体
// 需要方法和属性
class Student {
//成员属性---静态特征的描述
private boolean sex; //一般使用私有属性,共有的get/set方法
//成员方法---提供的功能描述
public boolean getSex(){
return this.sex;
}
//不允许修改sex,所以不提供set方法
protected void setSex(Boolean sex){ //如果在特殊情况下允许修改,可以使用范围限定词进行表示
this.sex=sex;
}
}
//构建对象
Student s1=new Student();
s1.setSex(true);
s1.setSex(false); //是否允许取绝于限制
封装有三大好处
- 良好的封装能够减少耦合
- 类内部的结构可以自由修改
- 可以对成员进行更精确的控制
- 隐藏信息,实现细节
4个关键字
用于进行访问控制
//一个文件种可以定义无数个类,但是只能有一个public class公共类
public class Student { //类的范围限定词分为2种情况。外部类的范围限定词可以使用无范围 限定词和public两种;而内部类上可以使用4种范围限定
//成员属性,类种包含哪些静态特征取决于问题本身
private Long id; //private只能在当前类中直接访问
protected String name; //protected可以在同包或者子类中直接访问
int age;//没有范围限定词,默认或者package限定词,只能在同包中直接访问
public double salary;//public到处可见
//一般规则是私有属性,共有的get/set方法
}
[点击并拖拽以移动]
记忆的方法
当前类内 | 同包 | 子类 | 到处 | |
---|---|---|---|---|
private | T | |||
无范围限定词 | T | T | ||
protected | T | T | T | |
public | T | T | T | T |
类定义规则:要求类内高内聚,类间弱耦合
- 封装确实可以使容易地修改类的内部实现,而无需修改使用了该类的客户代码
练习
案例:
声明公民类
Citizen
,包含属性:姓名,生日,身份证号,其中姓名是
String
类型,生日是
MyDate
类型身份证号也是
String
类型。
声明
T01
测试类,在
main
方法中创建你们家庭成员的几个对象,并打印信息。
public class MyDate {
private int year, month, date;
// 读取器,用于获取对象种的私有属性值
public int getYear() {
return year;
}
// 设置器,用于向对象种传入特定的属性值
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
if (month > 0) {
if(month>12) {
int y = month / 12;
if (y > 0)
year += y;
month %= 12;
}
} else {
int y = month / 12 - 1;
year += y;
month = (-1 * y) * 12 + month;
}
this.month = month;
}
public int getDate() {
return date;
}
public void setDate(int date) {
if (date > 0) {
while (true) {
if (date > getMaxDate()) {
date = date - getMaxDate();
month++;
}
if (getMaxDate() >= date)
break;
}
}
this.date = date;
}
private int getMaxDate() {
int res = 0;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
res = 31;
break;
case 4:
case 6:
case 9:
case 11:
res = 30;
break;
case 2:
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
res = 29;
} else
res = 28;
break;
default:
res = 0;
break;
}
return res;
}
public String show() {
return year + "年" + month + "月" + date + "日";
}
}
public class Citizen {
private String name;
private MyDate birth;
private String cardNo;
public void show() {
System.out.println("姓名:"+name+",生日:"+birth.show()+",身份证号:"+cardNo);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public MyDate getBirth() {
return birth;
}
public void setBirth(MyDate birth) {
this.birth = birth;
}
public String getCardNo() {
return cardNo;
}
public void setCardNo(String cardNo) {
this.cardNo = cardNo;
}
}
public class T01 {
public static void main(String[] args) {
Citizen[] cs = new Citizen[3];
cs[0] = new Citizen();
cs[0].setName("小黑");
MyDate md1 = new MyDate();
md1.setYear(2022);
md1.setMonth(12);
md1.setDate(20);
cs[0].setBirth(md1);
cs[0].setCardNo("610525199902152335");
cs[1] = new Citizen();
cs[1].setName("小白");
MyDate md2 = new MyDate();
md2.setYear(2021);
md2.setMonth(6);
md2.setDate(20);
cs[1].setBirth(md2);
cs[1].setCardNo("610525199902152335");
for (int i = 0; i < cs.length; i++) {
if (cs[i] != null)
cs[i].show();
}
}
}
案例:
声明一个数组管理工具类
MyArrays
,包含如下方法:
1
、
void sort(int[] arr)
:可以为任意一维整型数组
arr
实现从小到大排序
2
、
int indexOf(int[] arr, int value)
:可以在任意一维整型数组
arr
中使用折半查找法查找
value
值的下
标,如果不存在返回
-1
3
、
int[] copy(int[] arr, int len)
:可以实现从任意一维数组
arr
中复制一个新数组返回,新数组的长度为len
,从
arr[0]
开始复制
声明一个
Test07
测试类,并在
main
方法中调用测试
public class MyArrays {
void sort(int[] arr) {
for (int i = 1; i < arr.length; i++) {
for (int k = 0; k < arr.length - i; k++) {
if (arr[k] > arr[k + 1]) {
int tmp = arr[k];
arr[k] = arr[k + 1];
arr[k + 1] = tmp;
}
}
}
}
int indexOf(int[] arr, int value) {
sort(arr);
int index = -1;
int min = 0;
int max = arr.length - 1;
while (min <= max) {
int pos = (min + max) / 2;
if (arr[pos] < value)
min = pos + 1;
else if (arr[pos] > value)
max = pos - 1;
else {
index = pos;
break;
}
}
return index;
}
int[] copy(int[] arr, int len) {
int[] res = new int[len];
int c = 0;
for (int k = 0; k < res.length; k++) {
res[k] = arr[c++];
c = c % arr.length;
}
return res;
}
}
public class Test01 {
public static void main(String[] args) {
int[] arr = { 2, 3, 7, 5, 6, 1 };
MyArrays ma = new MyArrays();
ma.sort(arr);
for (int b1 : arr)
System.out.print(b1);
int pos = ma.indexOf(arr, 5);
System.out.println(pos);
int[] brr = ma.copy(arr, 10);
for (int tmp : brr)
System.out.print(tmp + "\t");
}
}