今天我们来从零开始实现图书管理系统。
图书管理系统
来看我们的具体的实现,上述视频。
我们首先来实现框架,我们要实现图书管理系统,首先要搭框架。
我们首先定义一个书包,在书包中定义一个书类和一个书架类,再定义一个用户包,其中包含用户类,管理者类,普通用户类,在定义一个工具包来实现具体操作,定义一个主函数。
我们先来实现Book类
public class Book {
private String name;
private String author;
private int price;
private String type;
private boolean isBorrowed;
public Book(String name, String author, int price, String type) {
this.name = name;
this.author = author;
this.price = price;
this.type = type;
}
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 int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public boolean isBorrowed() {
return isBorrowed;
}
public void setBorrowed(boolean borrowed) {
isBorrowed = borrowed;
}
public String toString(){
return "Book{" + "姓名:" + name + '/' +
"作者:" + author + '/' + "价格:" +
price + '/' + "类型" + type + '/'
+ ((isBorrowed==true)?"已借阅":"未借出");
}
}
我们对书进行描述的类,包含书名,作者名,价格,类型,和书是否被借出的状态,我们提供对name,author,price,type初始化的构造方法,为什么不对isborrowed进行初始化呢,因为boolean开始就是false,我们在进行ALT + Insert对所有字段提供getter and setter因为我们的权限是private。
最后对toString函数进行重写,来保证我们使用System.out.println()的时候可以输出我们book,对象的全部属性,那么这个((isborrowed)?已借阅":"未借出")是什么呢,我们isBorrowed默认是false所以默认是未借出,当我们后期修改isBorrow的时候就能达到true是已借阅的情况了。用的条件表达式,如果isBorrowed==true那么就是已借阅否则就是未借出。
我们下面实现书架类
public class BookList {
Book[] Books = new Book[10];
private int usedSize;
public BookList(){
this.Books[0] = new Book("三国演义","罗贯中",20,"小说");
this.Books[1] = new Book("西游记","吴承恩",38,"小说");
this.Books[2] = new Book("红楼梦","曹雪芹",30,"小说");
this.usedSize=3;
}
public int getUsedSize() {
return usedSize;
}
public void setUsedSize(int usedSize) {
this.usedSize = usedSize;
}
public Book[] getBooks() {
return Books;
}
public void setBooks(Book[] books) {
Books = books;
}
}
我们首先创建一个数组,我们用书类来定义一个书类数组,类似实现书架的功能,再定义usedSize来表示书架上到底有多少书,再提供构造方法的时候我们除了初始化我们的uesdSize,还要再Books数组中放入3本书来保证我们创建书架的时候就已经有书了,再提供Books数组和usedSize的Getter和Setter,Books数组的Gette和Setter有问题,我们后面再说
我们再来定义main类来跑程序
我们看我们运行的时候,
会有一个登录界面,我们在Main类中实现它
public class Main {
public static void login(){
}
public static void main(String[] args) {
BookList bookList = new BookList();
login();
}
}
我们在Main类中创建了一个书架对象,生成了刚才创建的三本书,我们通过login函数来实现登录界面
public static void login(){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你的姓名");
String name = scanner.nextLine();
System.out.println("请输入你的身份 1, 管理员 2, 用户");
String choice = scanner.nextLine();
}
我们实现了输入并用name记住了姓名,用choice记住了选择
我们还可以去设计密码来限制是否为管理员登入
public static void login(){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你的姓名");
String name = scanner.nextLine();
System.out.println("请输入你的身份 1, 管理员 2, 用户");
int choice = scanner.nextInt();
if(choice==1){
while (true){
System.out.println("请输入密码");
int count = scanner.nextInt();
if(count==123456){
System.out.println("密码正确");
return;//进入管理员菜单
}
else{
System.out.println("是否重新输入密码 1,是 2,否");
int count2 = scanner.nextInt();
if(count2==1){
continue;
}
else {
break;
}
}
}
}
return;
}
我们用循环和if语句来实现个简单的密码限制,这里就不过多描述了,我们既然有了选择,就要实现两个类来创建不同的对象,
这样就实现了两个不同的用户菜单,这里菜单名字忘改了,但是他们对书架操作的权限是不同的
我们现在来实现这个用户类
public abstract class User {
protected String name;
public User(String name){
this.name = name;
}
public abstract int menu();
}
我们创建了三个类,User是我们的父类,而其他两个是我们的子类,为什么要这样设计呢,因为我们在Main类运行代码的时候,调用一个父类User来利用多态,对字类重写的方法进行调用会更好,就刚才我们进行的选择,我们会创建不同的对象,密码正确我们会创建AdminUser对象,NormalUser对象,而使用继承我们可以直接把他向上转型为User类,用Uesr类来调用,话不多说我们直接上代码
先导入我们需要的包,
在子类AdminUser中操作
public class AdminUser extends User{
public AdminUser(String name){
super(name);
}
@Override
public int menu() {
System.out.println("欢迎" + name + "管理员" + "来到电子图书馆");
Scanner scanner = new Scanner(System.in);
System.out.println("****管理员菜单****");
System.out.println("1. 新增图书");
System.out.println("2. 删除图书");
System.out.println("3. 查找图书");
System.out.println("4. 展示图书");
System.out.println("0. 退出系统");
System.out.println("****************");
return 0;
}
}
在之前的Main中如果是管理员的话返回一个新的管理员对象,但是问题来了我们返回值不是void吗、
我们将返回值给上User这下不彻底穿起来了,我们就可以用user来访问管理员对象了,使用了我们的多态
public class NormalUser extends User {
public NormalUser(String name) {
super(name);
}
public int menu() {
System.out.println("欢迎" + name + "用户" + "来到电子图书馆");
Scanner scanner = new Scanner(System.in);
System.out.println("****用户菜单****");
System.out.println("1. 借阅图书");
System.out.println("2. 归还图书");
System.out.println("3. 查找图书");
System.out.println("0. 退出系统");
System.out.println("****************");
return 0;
}
}
在把用户的写了,我们再主类中去调用
再完整的展示下login函数
public static User login(){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你的姓名");
String name = scanner.nextLine();
System.out.println("请输入你的身份 1, 管理员 2, 用户");
int choice = scanner.nextInt();
if(choice==1){
while (true){
System.out.println("请输入密码");
int count = scanner.nextInt();
if(count==123456){
System.out.println("密码正确");
return new AdminUser(name);//进入管理员菜单
}
else{
System.out.println("是否重新输入密码 1,是 2,否");
int count2 = scanner.nextInt();
if(count2==1){
continue;
}
else {
break;
}
}
}
}
return new NormalUser(name);
}
可以根据不同的选择返回管理员对象,或者用户对象
public static void main(String[] args) {
BookList bookList = new BookList();
User user = login();
while(true){
user.menu();
}
}
我们就可以用父类user 来接收我们传过来的对象,发生了向上转型,我们可以通过user来调用我们在子类中重写的menu方法来显示不同的菜单
我们这时候运行就会显示两种不同的菜单,可以会有同学不明白为啥meun函数返回值是int,因为就要进行我们接下来的操作对每个选项的实现,所以在菜单界面我们就要接受我们选择的选项
我们在Main类中接收我们的选择
接下来就要实现具体操作。
我们在工具类进行操作,想想我们要怎么通过菜单的调用就能调用出具体的方法呢,
我们定义了这些类,每个类包含了对应的方法,还是那个问题,怎么通过菜单来访问对应的方法呢,最直观的就是类中有这些方法,这时我们就要用到接口了,让每个操作都用到了这个接口,而我们的管理员类和普通用户类中让他有接口的数组,这个用户中有哪个操作接口数组中就包含哪个。话不多说,我们继续进行操作
我们创建一个接口
public interface IOPeration {
void work(BookList bookList);
}
让这个接口包含对书架操作的功能
让其他所有操作都包含这个接口
public class AddOPeration implements IOPeration{
@Override
public void work(BookList bookList) {
System.out.println("添加图书");
}
}
后面的就不一一列举了
我们在父类User中创建一个接口数组
public class NormalUser extends User {
public NormalUser(String name) {
super(name);
this.IOPerations = new IOPeration[]{
new ExitOPeration(),
new BorrowOPeration(),
new ReturnOPeration(),
new FindOPeration()
};
}
public int menu() {
System.out.println("欢迎" + name + "用户" + "来到电子图书馆");
Scanner scanner = new Scanner(System.in);
System.out.println("****用户菜单****");
System.out.println("1. 借阅图书");
System.out.println("2. 归还图书");
System.out.println("3. 查找图书");
System.out.println("0. 退出系统");
System.out.println("****************");
System.out.println("请输入您的操作");
int choice = scanner.nextInt();
return choice;
}
}
这样普通用户类就包含了他所需要的功能,我们的普通用户也彻底定义完了
public class AdminUser extends User{
public AdminUser(String name){
super(name);
this.IOPerations = new IOPeration[]{
new ExitOPeration(),
new AddOPeration(),
new DelOPeration(),
new FindOPeration(),
new ShowOPeration()
};
}
@Override
public int menu() {
System.out.println("欢迎" + name + "管理员" + "来到电子图书馆");
Scanner scanner = new Scanner(System.in);
System.out.println("****管理员菜单****");
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("请输入您的操作");
int choice = scanner.nextInt();
return choice;
}
}
管理员用户我们也彻底定义完了,接下来就是实现用户对每个操作的调用我们首先要解决遗留问题
就是刚才我们对书架中的Getter和Setter不合理
我们想得到的是具体的书,放置书到书架具体的位置
public Book getBooks(int pos) {
return Books[pos];
}
public void setBooks(int pos, Book book) {
Books[pos] = book;
}
父类用户中
public void DoOPeration(int choice, BookList bookList){
IOPerations[choice].work(bookList);
}
主类中
public static void main(String[] args) {
BookList bookList = new BookList();
User user = login();
while(true){
int choice = user.menu();
user.DoOPeration(choice,bookList);
}
}
这样我们就能在具体菜单中根据选择中进行具体的操作了
其他的我们就不一一展示了,接下来就是我们对操作的具体实现了,马上结束了不用心急。
1,结束类方法
public class ExitOPeration implements IOPeration{
@Override
public void work(BookList bookList) {
System.out.println("退出系统");
System.exit(0);
}
}
直接System.exit(0)意思为程序正常退出
2,查找类方法
public class FindOPeration implements IOPeration{
@Override
public void work(BookList bookList) {
System.out.println("查找图书");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你要查找的书名");
String name = scanner.nextLine();
int count = bookList.getUsedSize();
for (int i = 0; i < count; i++) {
Book book = bookList.getBooks(i);
if (book.getName().equals(name)){
System.out.println(book);
return;
}
}
System.out.println("没有这本书");
}
}
我们使用循环进行比较即可,如果name和我们book中的name相同就可以输出了
3,添加类方法
public Book[] getbooksize(){
return Books;
}
在书架booklist中定义一个得到数组的函数,方便我们获得长度,因为我们在进行添加书的时候要判断书架是否满了。再创建一个book对象把新输入的属性,生成一本新的数,在把书放到书架上,之后记录书多了一本。
public class AddOPeration implements IOPeration{
@Override
public void work(BookList bookList) {
System.out.println("添加图书");
Scanner scanner = new Scanner(System.in);
int size = bookList.getUsedSize();
int size2 = bookList.getbooksize().length;
if(size2==size){
System.out.println("书架满了,无法添加");
}
else {
System.out.println("请输入你要添加的书名");
String name = scanner.nextLine();
System.out.println("请输入你要添加的作者");
String author = scanner.nextLine();
System.out.println("请输入你要添加的类型");
String type = scanner.nextLine();
System.out.println("请输入你要添加的价格");
int price = scanner.nextInt();
Book book = new Book(name,author,price,type);
bookList.setBooks(size,book);
bookList.setUsedSize(size+1);
}
}
}
4,借阅类方法
在借阅方法中还是一样我们把查找的方法拿来,其实都是利用查找的方法,再扩展,
如果找到了,就把book的属性改为true就是已借出。
public class BorrowOPeration implements IOPeration{
@Override
public void work(BookList bookList) {
System.out.println("借阅图书");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你要借阅的书名");
String name = scanner.nextLine();
int count = bookList.getUsedSize();
for (int i = 0; i < count; i++) {
Book book = bookList.getBooks(i);
if (book.getName().equals(name)){
if(book.isBorrowed()==false){
book.setBorrowed(true);
System.out.println("借阅成功");
return;
}
else {
System.out.println("书已经被借走了");
return;
}
}
else{
System.out.println("没有这本书");
}
}
}
}
5,归还类方法
和借阅一模一样,就改下书的isBorrowed状态就行
public class ReturnOPeration implements IOPeration{
@Override
public void work(BookList bookList) {
System.out.println("归还图书");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你要归还的书名");
String name = scanner.nextLine();
int count = bookList.getUsedSize();
for (int i = 0; i < count; i++) {
Book book = bookList.getBooks(i);
if (book.getName().equals(name)){
if(book.isBorrowed()==true){
book.setBorrowed(false);
System.out.println("归还成功");
return;
}
else {
System.out.println("书已经归还了");
return;
}
}
else{
System.out.println("没有这本书");
}
}
}
}
6,展示类方法
更简单了,我们直接循环遍历我们的书架就行了
public class ShowOPeration implements IOPeration{
@Override
public void work(BookList bookList) {
System.out.println("展示图书");
int count = bookList.getUsedSize();
for (int i = 0; i < count; i++) {
Book book = bookList.getBooks(i);
System.out.println(book);
}
}
}
7,删除类方法
public class DelOPeration implements IOPeration{
@Override
public void work(BookList bookList) {
System.out.println("删除图书");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你要删除的书名");
String name = scanner.nextLine();
int pos = -1;
int i = 0;
int count = bookList.getUsedSize();
for (i=0; i < count; i++) {
Book book = bookList.getBooks(i);
if (book.getName().equals(name)){
break;
}
}
if (count==i){
System.out.println("你要删除的书不存在");
return;
}
for (int j = pos; j < count-1; j++) {
Book book = bookList.getBooks(j+1);
bookList.setBooks(j,book);
System.out.println("删除成功");
bookList.setUsedSize(count-1);
bookList.setBooks(count-1,null);
}
}
}
我们还是利用查找,找到了之后,利用顺序表尾删的方法就可以了,一个一个覆盖,减少书架usedsize的声明即可。
下面放上源码来方便大家学习
博客结合的通讯录 · 75122bd · 王涛c语言/test_c_study - Gitee.com