网站快照诊断,指数函数和对数函数,福州seo管理,WordPress 卡密购买插件基于往期学习的类和对象、继承、多态、抽象类和接口来完成一个控制台版本的 “图书管理系统”
在控制台界面中实现用户与程序交互
任务目标#xff1a;
1、系统中能够表示多本图书的信息
2、提供两种用户#xff08;普通用户#xff0c;管理员#xff09;
3、普通用户…基于往期学习的类和对象、继承、多态、抽象类和接口来完成一个控制台版本的 “图书管理系统”
在控制台界面中实现用户与程序交互
任务目标
1、系统中能够表示多本图书的信息
2、提供两种用户普通用户管理员
3、普通用户查看书籍列表查找图书借书还书
4、管理员查看书籍列表查找图书新增图书删除图书
任务实现
1、图书类
创建一个包 library 用来表示 图书管理系统 再创建 Book 类表示 一本的图书信息 在类里创建需要用到的属性书名作者价格类型是否被借出
package library;public class Book {private String name; //书名private String author; //作者private double price; //价格private String type; //类型private Boolean isBorrowed; //是否被借出//构造方法//当新增图书时默认是未被借出public Book(String name, String author, double price, String type) {this.name name;this.author author;this.price price;this.type type;this.isBorrowed false;}//提供 get/set 方法public String getName() {return name;}public void setName(String name) {this.name name;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author author;}public double getPrice() {return price;}public void setPrice(double price) {this.price price;}public String getType() {return type;}public void setType(String type) {this.type type;}public Boolean getBorrowed() {return isBorrowed;}public void setBorrowed(Boolean borrowed) {isBorrowed borrowed;}
}
2、图书列表类
创建一个 BookList 类用来管理多个书籍对象
package library;public class BookList {//创建数组来记录多本书的信息private Book[] books new Book[100];private int size 0;//当前数组中有效元素的个数//构造方法public BookList(){//默认添加几本书方便后续测试books[0] new Book(西游记,吴承恩,100.0,古典名著);books[1] new Book(高等数学,高斯,90.0,自然科学);books[2] new Book(福尔摩斯探案集,阿瑟·柯南·道尔,110,悬疑推理小说);size 3;}//提供 get/set 方法public int getSize() {return size;}public void setSize(int size) {this.size size;}public Book getBook(int index){return books[index];}public void setBooks(int index,Book book){books[index] book;}
}
3、用户类
因为 普通用户 和 管理员 是从 用户 中根据不同的权限分离出来的这里就涉及到了 继承 的知识让 子类 继承 父类 来减少代码量
package library.User;import library.IOperation;//用户父类派生出子类管理员和普通用户
public abstract class User {//这里用 protected 修饰 name可以让子类直接获取到不用 get/set 方法protected String name;//当前这个类能够进行哪些操作就往这个数组中添加对应的对象protected IOperation[] operations;//构造方法public User(String name) {this.name name;}//管理员和普通用户的权限不一样菜单面板也有所不同//但是在父类中没有办法确定使用哪个菜单所以可以写成抽象类让子类去进行重写//通过返回用户输入的序号来决定执行不同的操作所以使用 int 类//写成 抽象方法 后就需要将这个父类写成 抽象类public abstract int menu();
}
父类写到这我们就可以去创建子类
4、普通用户类NormalUser
import java.util.Scanner;public class NormalUser extends User{public NormalUser(String name) {super(name);}Overridepublic int menu() {//打印普通用户的菜单System.out.println();System.out.println(欢迎您 name !);System.out.println(1. 查看书籍列表);System.out.println(2. 按照名字查找图书);System.out.println(3. 借阅图书);System.out.println(4. 归还图书);System.out.println(0. 退出);System.out.println();System.out.println(请输入您的操作);Scanner scanner new Scanner(System.in);int choice scanner.nextInt();return choice;}
}
5、管理员类Admin
import java.util.Scanner;public class NormalUser extends User{public NormalUser(String name) {super(name);}Overridepublic int menu() {//打印普通用户的菜单System.out.println();System.out.println(欢迎您 name !);System.out.println(1. 查看书籍列表);System.out.println(2. 按照名字查找图书);System.out.println(3. 借阅图书);System.out.println(4. 归还图书);System.out.println(0. 退出);System.out.println();System.out.println(请输入您的操作);Scanner scanner new Scanner(System.in);int choice scanner.nextInt();return choice;}
}写到这里 书 和 用户 的代码还没有进行交互这就是面向对象程序设计的典型特点先创建核心的类/对象把 核心类/对象属性、方法 搞出来再通过主逻辑把多个 类/对象 串起来。
6、基本操作接口
创建接口是为了保证所有的类都提供 work 方法保证 work 的参数都是一致的也方便之后调用
这里不使用 接口 使用 抽象类 也是可以的主要是因为当前没有什么实例属性需要子类来继承前文中的用户有 name 属性需要被继承所以所以使用了抽象类当两种写法都可以时优先考虑使用接口 通过 Operation 把 用户 和 书 关联起来
package library.operation;import library.BookList;//通过这个接口来表示用户的一种基本操作
public interface IOperation {//给出抽象方法//此处操作的 work 方法是针对 “多本书” 来进行操作的//后续再创建操作相关的具体的类实现这个接口就要进一步实现这里的操作void work(BookList bookList);}
把操作单独提取成类 这些类都要实现自 IOperation 接口并且重写其中的 work 方法
package library.operation;import library.BookList;public class AddOperation implements IOperation{Overridepublic void work(BookList bookList) {}
}由于当前每个操作都实现了 IOperation 接口就只需要给这两种用户添加一个 IOperation[ ] 的数组保存能够支持的操作有什么就可以了
回到 普通用户 和 管理员 创建好数组并在数组里写上要实现的操作
普通用户的操作
数组是 普通用户 和 管理员 都需要所以直接在父类创建即可 public NormalUser(String name) {super(name);operations new IOperation[]{new ExitOperation(),new ListOperation(),new FindOperation(), new BorrowOperation(), new ReturnOperation()};}注意这里创建的是数组元素和元素直接用 “”隔开。
数组创建写在构造方法内实例化一个用户都要操作可以调用
管理员的操作 public Admin(String name) {super(name);operations new IOperation[]{new ExitOperation(),new ListOperation(),new FindOperation(),new AddOperation(),new DelOperation()};}
7、Main 类
当我们准备好了所有对象书、用户、操作就可以通过一个主逻辑将所有内容串起来
7.1 创建书籍管理对象
BookList bookList new BookList();
7.2 创建用户对象
这里的身份有两个所以需要写一个方法让用户自己选择一个身份
//实例化用户对象
User user login();//选择身份方法
private static User login(){//让用户输入自己的身份Scanner scanner new Scanner(System.in);System.out.println(请输入您的姓名);String name scanner.next();System.out.println(请输入你的身份(1 普通用户2 管理员));int role scanner.nextInt();if(role 1){return new NormalUser(name);} else if (role 2) {return new Admin(name);}else {System.out.println(输入有误);return null;}
}
7.3 构建一个主循环
用户可以不断选择要进行的操作
while(true){}
7.4 显示用户对应的菜单
while(true){//这里会触发多态根据实际指向来决定是谁的菜单int choice user.menu();
}
7.5 根据序号执行对应操作
//给user 提供一个对应的 “执行” 的方法最终都是落到对应的 IOperation 对象上
user.work(choice,bookList);//回到 User 类里创建对应方法
public void work(int choice, BookList bookList){//这个操作是通过输入的 choise 值选择数组中对应的那个操作//这里每个操作的下标要和菜单上的序号一一对应//这里还可以添加一个判断判断输入的数字是否合法if(choice 0 choice operations.length){System.out.println(输入的选项非法);return;}operations[choice].work(bookList);
}
当主逻辑写到这里就可以进行测试了 测试顺利就可以进入最后的 操作实现
8、IOperation 操作实现
8.1 ExitOperation
package library.operation;import library.BookList;public class ExitOperation implements IOperation{Overridepublic void work(BookList bookList) {//只需要结束整个程序System.out.println(Goodbye);//这里的参数是程序的退出码不重要System.exit(0);}
} 8.2 ListOperation
package library.operation;import library.Book;
import library.BookList;public class ListOperation implements IOperation{Overridepublic void work(BookList bookList) {System.out.println(查看书籍列表);for(int i 0 ; i bookList.getSize();i){Book book bookList.getBook(i);System.out.println([ i ] book);}}
}通过 for 循环对我们存储书的数组进行遍历循环的次数来自父类的 size 循环里分别指向图书列表每一个最后进行打印这里在打印时添加一个下标方便之后进行利用下标进行删除 我们会看到打印出来的结果是一段哈希码我们需要再写一个 toString 方法回到 Book类中
Override
public String toString() {return [ name , author , price , type , isBorrowed ];
} 这样就把我们的书籍列表打印出来了
8.3 AddOperation
让用户输入新的书籍并添加到书籍列表中
package library.operation;import jdk.swing.interop.SwingInterOpUtils;
import library.Book;
import library.BookList;import java.util.Scanner;public class AddOperation implements IOperation{Overridepublic void work(BookList bookList) {System.out.println(新增图书);Scanner scanner new Scanner(System.in);System.out.println(请输入一个书名);String name scanner.next();System.out.println(请输入作者);String author scanner.next();System.out.println(请输入价格);Double price scanner.nextDouble();System.out.println(请输入类型);String type scanner.next();Book book new Book(name,author,price,type);int size bookList.getSize();bookList.setBooks(size,book);bookList.setSize(size 1);System.out.println(新增图书完成);}
}
通过 书 的四个属性创建一本新的书先获取 size 再通过 size 来找到 书 存放的位置最后让 size1 表示当前图书的有效位置 可以看到已经成功将新书存入书籍列表中了
8.4 DelOperation 在写删除之前先来了解一个小知识当我们进行删除文件时总是能非常快速的完成无论文件大小删除都是一瞬间。因为在硬盘里当你进行删除时硬盘会将你所删除的这个文件在的位置声明这里没有东西实际上你的文件还是存在只是之后新的数据会覆盖在这个区域上。这也是文件误删后可以通过技术手段进行找回的原因 在这写删除仍然使用这个概念当我们删除图书时只需要将有效图书个数-1就可以书依然存在数组里但是不会显示出来。 这里又牵出了一个问题有效个数-1只会让最后一本图书不显示当删除的书不是最末尾的书呢所以这里可以将问题转换如果要删除其中一本只要让这本和最末尾的书进行交换即可
package library.operation;import library.BookList;import java.util.Scanner;public class DelOperation implements IOperation{Overridepublic void work(BookList bookList) {Scanner scanner new Scanner(System.in);System.out.println(输入要删除的图书序号);//创建变量 index 来记录要删除的图书的序号int index scanner.nextInt();//判断一下序号是否在范围内if(index0 || indexbookList.getSize()){System.out.println(序号有误);return ;}//判断删除的序号是不是最后一本if(index bookList.getSize() -1){//如果是最后一本就把 Size-1 bookList.setSize(bookList.getSize() -1);}else {//如果不是最后一本就要把最后一本复制到删除的序号位置// 修改图书要修改的下标要修改的图书 最后一本书的下标bookList.setBooks(index,bookList.getBook(bookList.getSize()-1));//最后也要让 Size-1bookList.setSize(bookList.getSize() -1);}System.out.println(删除成功);}
}删除前: 进行删除: 删除后: 原来在最后的福尔摩斯探案集就来到原来高等数学的位置,这样就算删除成功了
8.5 BorrowOperation
借阅只需要修改单个属性即可
package library.operation;import library.Book;
import library.BookList;import java.util.Scanner;public class BorrowOperation implements IOperation{Overridepublic void work(BookList bookList) {Scanner scanner new Scanner(System.in);System.out.println(输入要借阅的图书序号);int index scanner.nextInt();//这里将我们要借阅的图书实例化,才可以修改它的 BorrowBook book bookList.getBook(index);//因为Borrwed属性是布尔值,所以不需要去写 trueif(book.getBorrowed()){System.out.println(该书已被借阅);}else {//借阅成功后修改属性book.setBorrowed(true);System.out.println(借阅成功);}}
}借阅过程 借阅结果 8.6 ReturnOperation
归还图书也差不多,只需要修改一些内容
package library.operation;import library.Book;
import library.BookList;import java.util.Scanner;public class ReturnOperation implements IOperation{Overridepublic void work(BookList bookList) {Scanner scanner new Scanner(System.in);System.out.println(输入要归还的图书序号);int index scanner.nextInt();Book book bookList.getBook(index);if(book.getBorrowed()){book.setBorrowed(false);System.out.println(归还成功);}else {System.out.println(该书未被借阅);}}
}8.7 FindOperation
这里写简单一些只通过书名来查找书的序号
package library.operation;import library.Book;
import library.BookList;import java.util.Scanner;public class FindOperation implements IOperation{Overridepublic void work(BookList bookList) {//输入姓名Scanner scanner new Scanner(System.in);String name scanner.next();//对所有图书进行遍历for(int i 0;i bookList.getSize();i){//对图书进行实例化Book book bookList.getBook(i);//判断字符串是否相等需要用到equalsif(book.getName().equals(name)){//相等则打印书籍信息System.out.println(book);}}System.out.println(查找结束);}
}完