封装
在面向对象程序设计方法中,封装Encapsulation是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。
1、封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问
反射机制
2、要访问该类的代码和数据,必须通过严格的接口控制。
3、封装最主要的功能在于能修改自己的实现代码,而不用修改那些调用代码的程序片段
4、适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。
封装有三大好处
良好的封装能够减少耦合类内部的结构可以自由修改可以对成员进行更精确的控制隐藏信息,实现细节
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 |
类定义规则:要求类内高内聚,类间弱耦合
封装确实可以使容易地修改类的内部实现,而无需修改使用了该类的客户代码
第一题
声明员工类
Employee
,包含属性:编号、姓名、年龄、薪资,
声明
Test01
测试类,并在
main
方法中,创建
2
个员工对象,并为属性赋值,并打印两个员工的信息。
package com.yan1;
public class Employee {
// 编号、姓名、年龄、薪资
private int bianHao;
private String xingMing;
private int nianLing;
private double xinZi;
public static void main(String[] args) {
Employee e1 = new Employee();
e1.setBianHao(1);
e1.setXingMing("张三");
e1.setNianLing(23);
e1.setXinZi(10000.);
e1.show();
Employee e2 = new Employee();
e2.setBianHao(2);
e2.setXingMing("李四");
e2.setNianLing(35);
e2.setXinZi(12000.);
e2.show();
}
public void show() {
System.out.println("员工" + bianHao + ",姓名" + xingMing + ",年龄" + nianLing + ",薪资" + xinZi);
}
// 读取器,用于获取对象中的私有属性值
public int getBianHao() {
return bianHao;
}
// 设置器,用于向对象中传入特定的属性值
public void setBianHao(int bianHao) {
this.bianHao = bianHao;
}
public String getXingMing() {
return xingMing;
}
public void setXingMing(String xingMing) {
this.xingMing = xingMing;
}
public int getNianLing() {
return nianLing;
}
public void setNianLing(int nianLing) {
this.nianLing = nianLing;
}
public double getXinZi() {
return xinZi;
}
public void setXinZi(double xinZi) {
this.xinZi = xinZi;
}
}
第二题
声明一个日期类
MyDate
,包含属性:年、月、日
声明一个
Test02
测试类,并在
main
方法中,创建
3
个日期对象,一个是你的随意写的日期,一个是今天的日期,一个是今年过年的日期,并打印显示
package com.yan1;
public class MyDate {
// 声明类MyDate,包含属性:年、月、日
private int year;
private int month;
private int date;
public static void main(String[] args) {
MyDate m1 = new MyDate();
m1.setYear(2000);
m1.setMonth(12);
m1.setDate(32);
m1.show1();
MyDate m2 = new MyDate();
m2.setYear(2022);
m2.setMonth(5);
m2.setDate(30);
m2.show1();
MyDate m3 = new MyDate();
m3.setYear(2022);
m3.setMonth(7);
m3.setDate(4);
m3.show1();
}
public String show() {
return year + " 年 " + month + " 月 " + date + " 日";
}
public void show1() {
System.out.println(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) {
int y = month / 13;
if (y > 0) {
year += y;
}
month %= 13;
} else {
int y = month / 12 - 1;
year += y;
month = (-1 * y) * 12 + month;
}
this.month = month;
}
public int getDay() {
return date;
}
public int getMaxDate(int month) {
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 void setDate(int date) {
if (date > 0) {
while (true) {
if (date > getMaxDate(month)) {
date = date - getMaxDate(month);
month++;
setMonth(month);
}
if (getMaxDate(month) >= date) {
break;
}
}
}
this.date = date;
}
}
第三题
声明公民类
Citizen
,包含属性:姓名,生日,身份证号,其中姓名是
String
类型,生日是
MyDate
类型,身份证号也是String
类型。
声明
Test03
测试类,在
main
方法中创建你们家庭成员的几个对象,并打印信息。
package com.yan1;
public class Citizen {
// 声明公民类Citizen,包含属性:姓名、生日、身份证号,其中姓名是String类型,身份证号也是String类型,生日是MyDate类型
// 声明Test3测试类,在main方法中创建家庭成员的几个对象,并打印信息
private String name;
private MyDate birth;
private String cardNum;
public static void main(String[] args) {
Citizen[] c1 = new Citizen[5];
c1[0] = new Citizen();
c1[0].setName("张三");
MyDate m1 = new MyDate();
m1.setYear(2020);
m1.setMonth(3);
m1.setDate(20);
c1[0].setBirth(m1);
c1[0].setCardNum("609878202003203214");
c1[1] = new Citizen();
c1[1].setName("李四");
MyDate m2 = new MyDate();
m2.setYear(2021);
m2.setMonth(6);
m2.setDate(21);
c1[1].setBirth(m2);
c1[1].setCardNum("987867202106213421");
c1[2] = new Citizen();
c1[2].setName("王五");
MyDate m3 = new MyDate();
m3.setYear(2022);
m3.setMonth(2);
m3.setDate(28);
c1[2].setBirth(m3);
c1[2].setCardNum("123243202202283214");
c1[3] = new Citizen();
c1[3].setName("孙六");
MyDate m4 = new MyDate();
m4.setYear(2012);
m4.setMonth(9);
m4.setDate(24);
c1[3].setBirth(m4);
c1[3].setCardNum("566553212209243233");
for (int i = 0; i < c1.length; i++) {
if (c1[i] != null) {
c1[i].show();
}
}
}
public void show() {
System.out.println("姓名:" + name + ",出生日期:" + birth.show() + ",身份证号码:" + cardNum);
}
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 getCardNum() {
return cardNum;
}
public void setCardNum(String cardNum) {
this.cardNum = cardNum;
}
}
第四题
声明一个日期类
MyDate
,包含属性:年、月、日,并在
MyDate
类中声明几个方法:
1
、
boolean isLeapYear()
:判断当前日期的是闰年吗?
2
、
void set(int y, int m, int d)
:修改年,月,日为新日期
3
、
void puls(int years, int months, int days)
:加上
years
年,
months
月,
days
天后的日期
并在测试类
Test04
的
main
方法中创建对象,并调用测试
package com.yan2;
public class MyDate {
//
private int year;
private int month;
private int date;
public static void main(String[] args) {
// int[] arr = new int[] { 3, 4, 9, 8, 7, 6, 5, 3, 2, 1 };
// Arrays.sort(arr);
// System.out.println(Arrays.toString(arr));// 排序输出
MyDate md = new MyDate();
md.setYear(2000);
md.setMonth(14);
md.setDate(6);
// md.set(1999, 3, 4);
// md.plus(12, 9, 26);
md.show();
System.out.println(md.isLeapYear());
}
public void show() {
System.out.println(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) {
int y = month / 13;
if (y > 0) {
year += y;
}
month = month % 13;
} else {
int y = month / 12;
year += y;
month = (-1 * y) * 12 + month;
}
this.month = month;
}
public int getDate() {
return date;
}
public int getMaxDate(int month) {
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 (isLeapYear()) {
res = 29;
} else {
res = 28;
}
break;
default:
res = 0;
break;
}
return res;
}
public void setDate(int date) {
if (date > 0) {
while (true) {
if (date > getMaxDate(month)) {
date = date - getMaxDate(month);
month++;
setMonth(month);
}
if (getMaxDate(month) >= date) {
break;
}
}
}
this.date = date;
}
// 判断当前日期是闰年
boolean isLeapYear() {
return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
}
// 修改年,月,日为新日期
void set(int y, int m, int d) {
// year=y;
// month=m;
// date=d;
setYear(y);
setMonth(m);
setDate(d);
}
// 加上years年,months月,days天后的日期
void plus(int years, int months, int days) {// plus加
setYear(years + year);
setMonth(months + month);
setDate(days + date);
}
}
第五题
声明一个三角形类
Triangle
,包含属性:
a,b,c
,表示三条边,包含几个方法:
1
、
boolean isRightTriangle()
:判断是否是一个直角三角形
2
、
boolean isIsoscelesTriangle()
:判断是否是一个等腰三角形
3
、
boolean isEquilateralTriangle()
:判断是否是一个等边三角形
4
、
double getArea()
:根据三条边,用海伦公式求面积
5
、
double getLength()
:求周长
并在测试类
Test05
的
main
方法中调用测试
package com.yan2;
public class Triangle {
// 声明一个三角形类Triangle,包含属性:a,b,c,表示三条边,包含几个方法:
// 1、boolean isRightTriangle:判断是否是一个直角三角形
// 2、boolean isIsoscelesTriangle:判断是否是一个等腰三角形
// 3、boolean isEquilateralTriangle:判断是否是一个等边三角形
// 4、double getArea():用海伦公式求面积
// 5、double getLenth():周长
private int a, b, c;
private boolean isTriangle() {
// 规则:两边之和大于第三边
return a + b > c && a + c > b && b + c > a;
}
double getArea() {
double p = (a + b + c) / 2;
return Math.sqrt(p * (p - a) * (p - b) * (p - c));
}
int getLength() {
return a + b + c;
}
boolean isRightTriangle() {// 直角三角形
if (isTriangle()) {
return (a * a + b * b == c * c) || (b * b + c * c == a * a) || (a * a + c * c == b * b);
}
return false;
}
boolean isIsoscelesTriangle() {// 等腰三角形
if (isTriangle()) {
return a == b || a == c || b == c;
}
return false;
}
boolean isEquilateralTriangle() {// 等边三角形
if (isTriangle()) {
return a == b && b == c;
}
return false;
}
public static void main(String[] args) {
Triangle t = new Triangle();
t.setA(3);
t.setB(4);
t.setC(5);
System.out.println(t.getLength());
System.out.println(t.getArea());
System.out.println(t.isEquilateralTriangle() ? "是等边三角形" : "不是等边三角形");
System.out.println(t.isIsoscelesTriangle() ? "是等腰三角形" : "不是等腰三角形");
System.out.println(t.isRightTriangle() ? "是直角三角形" : "不是直角三角形");
}
//============================================
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
public int getC() {
return c;
}
public void setC(int c) {
this.c = c;
}
}
第六题
声明一个数学计算工具类
MathTools
,包含如下方法:
1
、
int add(int a, int b)
:求
a+b
2
、
int subtract(int a,int b)
:求
a-b
3
、
int mutiply(int a, int b)
:求
a*b
4
、
int divide(int a, int b)
:求
a/b
5
、
int remainder(int a, int b)
:求
a%b
6
、
int max(int a, int b)
:求
a
和
b
中的最大值
7
、
int min(int a, int b)
:求
a
和
b
中的最小值
8
、
boolean equals(int a, int b)
:判断
a
和
b
是否相等
9
、
boolean isEven(int a)
:判断
a
是否是偶数
10
、
boolean isPrimeNumer(int a)
:判断
a
是否是素数
11
、
int round(double d)
:返回
d
的四舍五入后的整数值
声明一个
Test06
测试类,并在
main
方法中调用测试
package com.yan2;
public class MathTools {
// 1、int add(int a,int b):求a+b
// 2、int subtract(int a,int b):求a-b
// 3、int mutiply(int a,int b):求a*b
// 4、int divide(int a,int b):求a/b
// 5、int remainder(int a,int b):求a%b
// 6、int max(int a,int b):求a和b的最大值
// 7、int min(int a,int b):求a和b的最小值
// 8、boolean equals(int a,int b):判断a和b是否相等
// 9、boolean isEven(int a):判断a是否是偶数
// 10、boolean isPrimeNumber(int a):判断a是否为素数
// 11、int round(double d):返回d的四舍五入后的整数值
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
int mutiply(int a, int b) {
return a * b;
}
int divide(int a, int b) {
if (b != 0) {
return a / b;
}
return 0;
}
int remainder(int a, int b) {
if (b != 0) {
return a % b;
}
return Integer.MIN_VALUE;
}
int max(int a, int b) {
if (a > b) {
return a;
}
return b;
}
int min(int a, int b) {
return a < b ? a : b;
}
boolean equals(int a, int b) {
return a == b;
}
boolean doubleEquals(double a, double b) {
return Math.abs(a - b) < 1e-6;
}
boolean isEven(int a) {
return a % 2 == 0;
}
boolean isOdd(int a) {
return !isEven(a);
}
boolean isPrimeNumber(int a) {
boolean res = true;
for (int i = 2; i < a; i++) {
if (a % i == 0) {
res = false;
break;
}
}
return res;
}
int round(double d) {
if (d < Integer.MAX_VALUE && d > Integer.MIN_VALUE) {
return (int) Math.round(d);
}
return -1;
}
}
第七题
声明一个数组管理工具类
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
方法中调用测试
package com.yan2;
public class MyArrays {
// void sort(int[] arr):可以为任意一维整型数组arr实现从小到大排序
// int indexOf(int[] arr,int value):可以在任意一维整型数组arr中查找value值的下标,如果不存在返回-1
// int[] copy(int[] arr,int len):可以从任意一维数组arr中复制一个新数组返回,新数组长度为len,从arr[0]开始复制
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 cc = 0;
for (int i = 0; i < res.length; i++) {
res[i] = arr[cc++];
cc = cc % arr.length;
}
return res;
}
public static void main(String[] args) {
int[] arr = new int[] { 2, 6, 4, 1, 9, 5 };
MyArrays ma = new MyArrays();
// ma.sort(arr);
// for (int tmp : arr) {
// System.out.print(tmp + "\t");
// }
// int pos = ma.indexOf(arr, 9);
// System.out.println("\n" + pos);
int[] brr = ma.copy(arr, 20);
int count = 0;
for (int tmp : brr) {
System.out.print(tmp + "\t");
count++;
if (count % 6 == 0)
System.out.println();
}
}
}
第八题
声明一个常识工具类
DateCommonsTools
,包含如下方法:
1
、
String getWeekName(int week)
:根据星期值,返回对应的中文名称,例如星期一
2
、
String getMonthName(int month)
:根据月份值,返回对应的英语单词
3
、
int getTotalDaysOfMonth(int year, int month)
:返回某年某月的总天数
4
、
int getTotalDaysOfYear(int year)
:获取某年的总天数
5
、
boolean isLeapYear(int year)
:判断某年是否是闰年
声明一个
Test08
测试类,并在
main
方法中调用测试
package com.yan2;
public class DateCommonsTools {
// String getWeekName(int week):跟据星期值,返回对应的英文单词
// String getMonthName(int month):根据月份值,返回对应的英语单词
// int getTotalDaysOfMonth(int year,int month):返回某年某月的总天数
// int getTotalDaysOfYear(int year):获取某年的总天数
// boolean isLeapYear(int year):判断某年是否是闰年
String getWeekName(int week) {
String[] arr = new String[] { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
if (week >= 0) {
return arr[week % arr.length];
}
return "未知";
}
String getMonthName(int month) {
String[] brr = new String[] { "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" };
if (month >= 0) {
return brr[month % brr.length];
}
return "未知";
}
int getTotalDaysOfMonth(int year, int month) {
int day = 0;
for (int i = 0; i < month - 1; i++) {
switch (i) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
day = 31;
break;
case 4:
case 6:
case 9:
case 11:
day = 30;
break;
case 2:
if (isLeapYear(year))
day = 29;
else
day = 28;
break;
default:
day = 0;
break;
}
}
return day;
}
int getTotalDaysOfYear(int year) {
int day = 0;
if (isLeapYear(year)) {
day = 366;
} else {
day = 365;
}
return day;
}
boolean isLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
public static void main(String[] args) {
}
}