目录
前言
本文为封装的学习笔记,刚开始学习Java,有错误及不完善的地方还请大佬们指出~
1. 包(package)
本质上是文件夹,用于区分同名的类。完整的类名为包名.类名,例如:pack01.Person
- 包的声明:写在java文件第一行
package pack0705.exercise01;// 声明该类在包pack0705下子包exercise01中
public class Test { // 声明类,类名为Test
}
- 命名规则及规范:
- 规则:
- 只能使用字母、数字、中文、下划线、$
- 数字不能在首位
- 不能使用关键字和保留字
- 规范:
- 不能使用中文
- 建议不要使用下划线和$
- 包名全小写
- 规则:
2. 类(class)
有共同特点的对象的集合,是一个不占据任何空间的抽象概念,用class关键字创建类
- 类的声明:
public class Person{} //声明一个Person类
- 命名规则及规范:
- 规则:与包的命名规则相同
- 规范:
- 不能使用中文
- 建议不要使用下划线和$
- 类名首字母建议大写、驼峰(每个单词首字母大写)
3. 对象
对象实际是把数据及对数据的操作方法放在一起的整体,拥有属性和方法两种描述
- 属性
- 描述对象的静态特点
- 定义及调用时没有括号
public class Person { //声明Person类
int age; //定义属性age
String name; //定义属性name
}
- 方法
- 描述对象的动态功能
- 分为方法声明和方法体两部分:方法声明 { 方法体 }
- 声明及调用时有括号(括号内可以有形式参数)
- 可以有返回值,无返回值时用void声明
public class Person {
public void sing() { //声明无返回值的sing方法
System.out.println("人在唱歌");
}
public int add(int a,int b) { //声明返回值为整型的add方法,括号内为形式参数
return a+b; //返回值为a+b
}
}
4. 封装
通过访问修饰符,给类中的属性和方法设定访问范围
4.1 访问修饰符
修饰符 \ 访问范围 | 任意包任意类 | 本包或其他包中的继承类 | 本包 | 本类 |
---|---|---|---|---|
public | √ | √ | √ | √ |
protected | × | √ | √ | √ |
不写(默认) | × | × | √ | √ |
private | × | × | × | √ |
4.2 属性访问器
提供Getter(获取)和Setter(修改)私有属性的方法,让用户可以在类外访问
快捷键:alt+insert
- Getter方法:只获得属性的值,不对属性进行修改
public class Person {
private String name;
public String getName() {
return name;
}
}
- Setter方法:获得属性值,并对其进行修改
public class Person {
private String name;
public void setName(String name) {
this.name = name;
}
}
4.3 封装的作用
- 防止属性被外部代码随意访问和修改
- 隐藏对象的实现细节,提高安全性
- 提高了代码的可维护性,又方便外部使用
- 降低了代码间的关联性,减少了代码冗余
5. 构造函数
又叫构造器,用于描述对象的初始化过程。
- 初始化规则:
- 函数名必须和类名相同
- 构造函数可以有多个
- 构造函数可以有形参
- tips:在没有创建构造函数时,jdk会自动创建一个无参数的构造函数;创建任意构造函数后,jdk自动创建的构造函数会停用
public class Person {
String name;
public Person() { //定义无参构造函数,初始化属性name值为"张三"
name = "张三";
}
public Person(String name) { //定义一个参的构造函数,初始化属性name为传递过来的名字
this.name = name;
}
public static void main(String[] args) {
Person p1 = new Person();//new Person对象,调用无参构造函数
System.out.println(p1.name);
Person p2 = new Person("李四");//new Person对象,调用一个参构造函数
System.out.println(p2.name);
}
}
- 运行结果:
6. 重载(overload)
一个类中的方法名字相同而形参不同,称为方法重载
- 重载条件:
- 在同一个类中
- 方法名相同
- 方法参数的个数、类型、顺序至少有一个不同
public class Person {
String name;
public Person() { //定义无参构造函数,初始化属性name值为"张三"
name = "张三";
}
public Person(String name) { //定义一个参的构造函数,初始化属性name为传递过来的名字
this.name = name;
}
public void sing() {
System.out.println(name + "在唱歌");
}
public void sing(String name) {
System.out.println(this.name + "在唱" + name);
}
public static void main(String[] args) {
Person p1 = new Person();
p1.sing();//调用无参sing方法
p1.sing("起风了");//调用一个参sing方法
}
}
- 运行结果:
7. 关键字
7.1 this关键字
用于指代本类的对象
- 属性名和方法中形参同名时,用 this.属性名 指代本类的属性
- 调用本类的属性和方法,无冲突时可以不写
- this(); 调用本类的构造函数,必须写在构造函数中,且必须是第一句
public class Person {
String name;
String address;
int age;
Person () {
age = 15;
}
public Person (String name,String address) {
this(); //调用无参构造函数
this.name = name; //属性和形参同名指代属性
this.address = address;
this.age(); //调用本类的age方法
}
public void age() {
age = 20;
}
}
7.2 static关键字
被static修饰的属性或方法不独属于类中任何一个对象,而是被类的对象所共享,即属于类的。
- static关键字的作用
- 建立静态代码块优化性能
- 通过类名调用属性方法,省去创建对象
- 静态变量和实例变量的区别
- 静态变量不属于任何实例对象,JVM只在创建时为其分配一次内存空间
- 实例变量在每次创建对象时,JVM都会分配一次内存空间
- static关键字的应用
- 修饰代码块
- 修饰成员属性
- 修饰成员方法(构造函数不是静态方法)
- 修饰内部类
- 【tips】不允许修饰局部变量
8. 练习Demo
题目:影碟出租管理系统
客户通过此程序借阅 / 归还影碟
- 思维导图
代码实现
- User.java
package pack0708;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class User{
private String id;
private String name;
private String pass;
private List<Disk> borrows = new ArrayList<>(); //存放用户借阅的影碟
public User(String id, String pass) {
this.id = id;
this.pass = pass;
}
public User(String id, String name, String pass) {
this.id = id;
this.name = name;
this.pass = pass;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(id, user.id) && Objects.equals(pass, user.pass);
}
@Override
public int hashCode() {
return Objects.hash(id, pass);
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
public List<Disk> getBorrows() {
return borrows;
}
public void setBorrows(List<Disk> borrows) {
this.borrows = borrows;
}
}
- Disk.java
package pack0708;
import java.util.Objects;
public class Disk {
private int id;
private String name;
private boolean status;
public Disk(int id) {
this.id = id;
}
public Disk(int id, String name) {
this.id = id;
this.name = name;
this.status = true;
}
@Override
public String toString() {
return id + "\t" + name + "\t" + (status?"未借出":"已借出"); //重新规定输出格式
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Disk disk = (Disk) o;
return id == disk.id;
}
@Override
public int hashCode() {
return Objects.hash(id);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
}
- Menu.java
package pack0708;
import java.util.Scanner;
public class Menu {
private static Scanner scan = new Scanner(System.in);
public static void startMenu() {
System.out.println("************************");
System.out.println("\t欢迎使用影碟出租系统");
System.out.println("************************");
System.out.println("\t\t1.注册");
System.out.println("\t\t2.登录");
System.out.println("\t\t3.退出");
int n = Tool.getN(1,3,"功能"); //获取正确的n值,用于选择功能
switch (n) {
case 1:
UserManager.registered(); //注册
break;
case 2:
User user = UserManager.login(); //登录
if (user == null) { //users集合中未找到输入的账号密码
System.out.println("账号或密码错误");
} else {
userMenu(user); //打开用户菜单
}
break;
case 3:
System.out.println("感谢使用影碟出租系统");
System.exit(1); //退出虚拟机,结束程序
break;
}
startMenu(); //虚拟机不结束则继续调用开始菜单
}
private static void userMenu(User user) {
System.out.println("欢迎【" + user.getName() + "】登录");
while (true) {
System.out.println("************************");
System.out.println("\t\t1.查看所有影碟");
System.out.println("\t\t2.借阅影碟");
System.out.println("\t\t3.归还影碟");
System.out.println("\t\t4.查看借阅的影碟");
System.out.println("\t\t5.退出");
int n = Tool.getN(1,5,"功能");
switch (n) {
case 1:
UserManager.inquireAllDisks(); //查看所有影碟
break;
case 2:
UserManager.borrowDisk(user); //借阅影碟
break;
case 3:
UserManager.returnDisk(user); //归还影碟
break;
case 4:
UserManager.inquireBorrowDisk(user); //查看用户借阅的所有影碟
break;
case 5:
System.out.println("已退出登录");
break;
}
if (n == 5) {
break; //选择5则跳出循环,退出用户菜单
}
}
startMenu(); //退出到开始菜单
}
}
- UserManager.java
package pack0708;
import java.util.*;
public class UserManager {
private static List<User> users = new ArrayList<>(); //存储所有用户信息
private static List<Disk> alldisks = new ArrayList<>(); //存储所有影碟信息
private static Scanner scan = new Scanner(System.in);
static { //将影碟存入alldisks集合
alldisks.add(new Disk(1, "复仇者联盟1"));
alldisks.add(new Disk(2, "复仇者联盟2"));
alldisks.add(new Disk(3, "复仇者联盟3"));
alldisks.add(new Disk(4, "复仇者联盟4"));
alldisks.add(new Disk(5, "速度与激情1"));
alldisks.add(new Disk(6, "速度与激情2"));
alldisks.add(new Disk(7, "速度与激情3"));
alldisks.add(new Disk(8, "速度与激情4"));
alldisks.add(new Disk(9, "速度与激情5"));
alldisks.add(new Disk(10, "速度与激情6"));
alldisks.add(new Disk(11, "速度与激情7"));
alldisks.add(new Disk(12, "战狼1"));
alldisks.add(new Disk(13, "战狼2"));
}
public static void registered() { //注册
System.out.print("请输入用户名:");
String name = scan.next();
System.out.print("请设置密码:");
String pass;
while (true) {
while (true) {
pass = scan.next();
if (Tool.checkPass(pass)) { //判断密码是否符合规定
break;
}
}
System.out.print("请确认密码:");
String repass;
repass = scan.next();
if (Tool.checkRepass(pass, repass)) {
System.out.print("注册成功,您的账号为:");
break;
} else {
System.out.print("密码不一致,请再次确认:");
repass = scan.next();
if (Tool.checkRepass(pass, repass)) {
System.out.print("注册成功,您的账号为:");
break;
} else {
System.out.print("两次确认失败,请重新设置密码:");
}
}
}
String id = Tool.getId(); //获取账号
System.out.println(id + ",您的账号将用于登录,请牢记");
users.add(new User(id, name, pass)); //将用户信息存入users集合
}
public static User login() { //登录
System.out.print("请输入账号:");
String id = scan.next();
System.out.print("请输入密码:");
String pass = scan.next();
User user = new User(id, pass); //用输入的账号密码新建一个User对象,用于和users中信息比对
int i = users.indexOf(user); //比对信息
if (i == -1) { //未找到说明系统中没有注册过该用户
System.out.print("登录失败");
return null;
} else {
return users.get(i); //比对成功,返回当前用户
}
}
public static void inquireAllDisks() { //查看所有影碟
System.out.println("编号\t影片名\t\t借阅状态");
for (Disk disk : alldisks) {
System.out.println(disk);
}
}
public static void borrowDisk(User user) { //借阅影碟
int n = Tool.getN(1,13,"影碟编号"); //获取正确的影碟编号
Disk disk = Tool.checkDisk(alldisks,n); //查找影碟是否存在
if (disk != null && disk.isStatus()) { //判断影碟存在且未被借阅
user.getBorrows().add(disk); //用户借阅集合中加入该影碟
disk.setStatus(false); //标记影碟状态为已借阅
System.out.println("借阅成功");
} else {
System.out.println("很抱歉该影碟已被借走");
}
}
public static void returnDisk(User user) { //归还影碟
int n = Tool.getN(1,13,"影碟编号");
Disk disk = Tool.checkDisk(user.getBorrows(),n);
if (disk != null) {
user.getBorrows().remove(disk);
disk.setStatus(true);
System.out.println("归还成功");
} else {
System.out.println("归还失败");
}
}
public static void inquireBorrowDisk(User user) { //查询用户借阅的影碟
System.out.println("您借阅的影碟信息如下:");
System.out.println("编号\t影片名\t\t借阅状态");
for (Disk borrow : user.getBorrows()) {
System.out.println(borrow);
}
}
}
- Tool.java
package pack0708;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public class Tool {
private static Scanner scan = new Scanner(System.in);
public static int getN(int start,int end,String content) { //获取正确的n值
System.out.print("请选择" + content + ":");
while (true) { //不正确则一直循环
try {
int n = scan.nextInt();
if (n >= start && n <= end) { //输入的n在给定范围内
return n;
} else {
System.out.print("没有此" + content + ",请重新选择:");
}
} catch (Exception ex) { //输入的n不是整数则抓异常让用户重新输入
System.out.print("请输入一个整数:");
scan = new Scanner(System.in);
}
}
}
public static boolean checkPass(String pass) { //检测密码是否符合长度要求
if (pass.length() < 3 || pass.length() > 6) {
System.out.print("密码长度必须在3-6位,请重新设置:");
return false;
}
return true;
}
public static boolean checkRepass(String pass, String repass) { //检测两次输入密码是否一致
if (pass.equals(repass)) {
return true;
}
return false;
}
public static String getId() { //获取6位随机账号
Random ran = new Random();
String id = "";
for (int i =0; i < 6; i++) {
int n = ran.nextInt(10);
id += n;
}
return id;
}
public static Disk checkDisk(List<Disk> disks, int n) { //检测影碟是否存在
for (Disk disk : disks) {
if (disk.getId() == n) {
return disk;
}
}
System.out.print("没有该影碟,");
return null;
}
}
- Test.java
package pack0708;
public class Test {
public static void main(String[] args) {
Menu.startMenu(); //启动开始菜单
}
}