图书管理系统是对java语法篇的一个总结,也是对语法篇学习效果的一个总结
要写出图书管理系统就要应用到较难的抽象类,接口,继承等内容,
所以对大家的语法是有一定基础要求的;
发车喽!!!!
相信平常大家都打过游戏或者使用过一些软件;
咱们不如就从咱们日常使用软件的体验来构思一下
总的来说大概分为三个步骤
肯定是登录账号密码;
然后就可以进入软件,
可以反复的,凭我们的意愿来使用该软件用户所拥有的功能;
那么用户应该有哪些功能呢?
图书馆,那普通用户就是去借阅书籍的,
有借阅功能就一定有归还功能,
那为了方便用户应该再写一个查询功能吧
方便用户来查找有没有这本书,这本书有没有被借出
那么用户就只有三个功能
使用完之后,退出软件;
肯定也是要先登录账号密码,
然后进入软件
也可以反复的来使用该软件管理员所拥有的功能,
但是管理员不是凭自己的意愿来使用这些功能,
而是为了维护这个软件比如说新到了一批书,
管理员要做的就是去把这些书登录到图书管理系统;
所以管理员的功能有哪些呢?
新书到了肯定要登录到系统里,那就是新增功能
如果那本书意外丢失,损毁那这本书就没办法被借出了,
所以也要有一个删除功能;
如果有老年人不会使用这个系统,那么就会去问值班人员,
所以也要有一个查询功能;
图书馆要去新增图书时,肯定要看自己有哪些书,没有哪些书,
所以要有一个显示图书(遍历图书)的功能;
那么管理员就有四个功能
肯定也是退出软件
首先存放在图书馆里的书,
会提供给用户一些属性,
方便他们快速找到自己想要的书
大致是以下属性:
public class Book {
private String name;
private String author;
private String type;
private int price;
private boolean isBorrowde;//是否被借出
public Book(String name, String author, String type, int price) {
this.name = name;
this.author = author;
this.type = type;
this.price = price;
}
}
因为有显示图书与查找图书的功能,
所以要重写toString方法
public String toString() {
return "Book{" +
"书名:'" + name + '\'' +
", 作者:'" + author + '\'' +
", 类型:'" + type + '\'' +
", 价格:" + price +
", " + ((isBorrowde == false)?" 未被借出":" 已被借出") +
'}';
}
这里使用了一个三木操作符,
因为boolean类型默认是false,
而新书肯定是未被借出的,
所以用false代表未被借出,
用true表示已被借出;
因为是一个系统,
所以数据不能是公开的,
所以要封装起来,
那么就要提供set与get方法
public boolean isBorrowde() {
return isBorrowde;
}
public void setBorrowde(boolean borrowde) {
isBorrowde = borrowde;
}
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 String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
所以Book类的全部代码就是
public class Book {
private String name;
private String author;
private String type;
private int price;
private boolean isBorrowde;//是否被借出
public Book(String name, String author, String type, int price) {
this.name = name;
this.author = author;
this.type = type;
this.price = price;
}
@Override
public String toString() {
return "Book{" +
"书名:'" + name + '\'' +
", 作者:'" + author + '\'' +
", 类型:'" + type + '\'' +
", 价格:" + price +
", " + ((isBorrowde == false)?" 未被借出":" 已被借出") +
'}';
}
public boolean isBorrowde() {
return isBorrowde;
}
public void setBorrowde(boolean borrowde) {
isBorrowde = borrowde;
}
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 String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
一个书架可以存放多本书,所以就使用数组来实现存放书这个功能
public class Bookshelf {
private static final int size = 10;
private Book[] books = new Book[size];
private int usedSize = 0;//记录书架上有多少本书
}
图书馆肯定是要有书的,所以咱们要提前存放进去一些书;
及构造方法:
public Bookshelf() {
books[0] = new Book("三国演义","罗贯中","小说",99);
books[1] = new Book("西游记","吴承恩","小说",99);
books[2] = new Book("红楼梦","曹雪芹","小说",99);
books[3] = new Book("水浒传","施耐庵","小说",99);
this.usedSize = 4;
}
因为有显示与查询功能,新增与删除功能所以要提供get与set方法
public Book[] getBooks() {
return books;
}
public void setBooks(Book books) {
this.books[usedSize] = books;
}
public int getUsedSize() {
return usedSize;
}
public void setUsedSize(int usedSize) {
this.usedSize = usedSize;
}
public int getSize() {
return size;
}
所以书架的全部代码就是
public class Bookshelf {
private static final int size = 10;
private Book[] books = new Book[size];
private int usedSize = 0;//记录书架上有多少本书
public Bookshelf() {
books[0] = new Book("三国演义","罗贯中","小说",99);
books[1] = new Book("西游记","吴承恩","小说",99);
books[2] = new Book("红楼梦","曹雪芹","小说",99);
books[3] = new Book("水浒传","施耐庵","小说",99);
this.usedSize = 4;
}
public Book[] getBooks() {
return books;
}
public void setBooks(Book books) {
this.books[usedSize] = books;
}
public int getUsedSize() {
return usedSize;
}
public void setUsedSize(int usedSize) {
this.usedSize = usedSize;
}
public int getSize() {
return size;
}
}
由于咱们目前的知识储备还不足以写出账号密码的登陆系统,
所以一切从简
输入姓名,让他自己选择身份吧;
等以后知识储备够了再回来完善;
账号密码登录一次就可以了
所以咱们完全可以写成一个静态方法,
不如就写在主函数所在的类里,
这样就不用通过类名来调用了,
也就是说咱们现在要写一个静态的登录方法,
登录之后要让用户去输入1或者其他数来判断他的身份,
那么就可以创建一个存放普通用户与管理员这两个类的包
他们就只有被提供的操作不同
这是管理员视角
那么要如何来提供相应的界面呢?
通过if语句来识别他输入的身份
然后返回不同的内容
首先创建一个实现管理系统的类
public class Main {
private static void login() {
System.out.println("请输入姓名");
Scanner scan = new Scanner(System.in);
String name = scan.nextLine();
System.out.println("请选择身份 1-> 管理员,0->普通用户");
int choice = scan.nextInt();
if(choice == 1) {
System.out.println("管理员登陆成功");
}
else {
System.out.println("普通用户登陆成功");
}
}
然后根据他的身份来提供不同的操作,
所以可以提供两个不同的菜单,
那咱们就可以用一个抽象类来存储名字,
并提供这个菜单方法,
因为不管是普通用户还是管理员都有名字,有成员变量;
所以不能定义成接口来提供菜单方法
因为这个类就是要被继承的,所以他的成员变量可以用protected来修饰
抽象类:
public abstract class User {
protected String name;
public User(String name) {
this.name = name;
}
public abstract int menu();
}
普通用户:
public class RegularUsers extends User{
public RegularUsers(String name) {
super(name);
}
public int menu() {
System.out.println("*************************");
System.out.println("欢迎 " + name + " 使用图书管理系统");
System.out.println(" 1.查找图书 ");
System.out.println(" 2.借阅图书 ");
System.out.println(" 3.归还图书 ");
System.out.println(" 0.退出系统 ");
System.out.println("*************************");
System.out.println("请输入要使用的操作");
}
}
管理员:
public class Administrator extends User{
public Administrator(String name) {
super(name);
}
public 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("请输入要使用的操作");
}
}
至此,用户登录相关的代码基本写完,
当然后续为了配合其他内容的实现肯定还要进行修改
这些操作都是基于书架上书的操作,
所以完全可以写一个接口
public interface Operation {
void work(Bookshelf bookshelf);
}
因为是要对书架上的书去实现操作,
所以该方法要接收的是一个书架类型的参数;
以下是创建的一个存放操作类的包
咱们先来编写这些功能的代码,最后再实现整个系统的整合;
上面书架提供了存放书的数组books,又提供了书架上已经有了多少本书usedSize,
那么如果要存放新书,直接存放到 books[usedSize] 这个位置就可以了;
public class NewPlus implements Operation {
@Override
public void work(Bookshelf bookshelf) {
Book[] books = bookshelf.getBooks();
System.out.println("新加一本书");
System.out.println("请输入书名");
Scanner scan = new Scanner(System.in);
String name = scan.nextLine();
System.out.println("请输入作者");
String author = scan.nextLine();
System.out.println("请输入类型");
String type = scan.nextLine();
System.out.println("请输入价格");
int price = scan.nextInt();
Book book = new Book(name,author,type,price);
bookshelf.setBooks(book);
bookshelf.setUsedSize(bookshelf.getUsedSize() + 1);
}
}
到这一步要思考一个问题,
如果这个书架上本身就存放这本书,
那么我就不需要新增这本书了;
所以要让这个新增功能增加一个甄别的功能,
作者可能相同,类型可能相同,价格可能相同,
但是只有名字不可能相同;
所以要在输入书名后,
用这个书名去和书架上的所有书去判断是否相同,
然后做出相应提示
所以最中新增功能的代码就是
public class NewPlus implements Operation {
@Override
public void work(Bookshelf bookshelf) {
Book[] books = bookshelf.getBooks();
System.out.println("新加一本书");
System.out.println("请输入书名");
Scanner scan = new Scanner(System.in);
String name = scan.nextLine();
for(int i = 0;i < bookshelf.getUsedSize();i++) {
if(books[i].getName().equals(name) == true) {
System.out.println("这本书已经存在了,不能再新增了");
return;
}
}
System.out.println("请输入作者");
String author = scan.nextLine();
System.out.println("请输入类型");
String type = scan.nextLine();
System.out.println("请输入价格");
int price = scan.nextInt();
Book book = new Book(name,author,type,price);
bookshelf.setBooks(book);
bookshelf.setUsedSize(bookshelf.getUsedSize() + 1);
}
}
与新增功能一样,只有名字是不可能相同的,
删除的不是最后一本书 | 删除的是最后一本书 |
---|---|
那就直接让数组后面的一本书去覆盖他,并且让usedSize - 1 ; | 那就可以直接赋给最后一本书null,让他不指向任何对象,并且让usedSize - 1; |
具体代码如下:
public class Delete implements Operation{
@Override
public void work(Bookshelf bookshelf) {
System.out.println("请输入要删除的书的书名");
Book[] books = bookshelf.getBooks();
Scanner scan = new Scanner(System.in);
String name = scan.nextLine();
for(int i = 0;i < bookshelf.getUsedSize();i++) {
if(books[i].getName().equals(name)) {
System.out.println("删除成功");
if(i == bookshelf.getSize() - 1) {
bookshelf.setBooks(null);
}
else {
for(;i < bookshelf.getUsedSize();i++) {
books[i] = books[i + 1];
}
break;
}
}
else if(i == bookshelf.getUsedSize() - 1) {
System.out.println("没有这本书");
return;
}
}
bookshelf.setUsedSize(bookshelf.getUsedSize() - 1);
}
}
这个功能的实现就比较简单了
public class DisPlay implements Operation {
@Override
public void work(Bookshelf bookshelf) {
Book[] books = bookshelf.getBooks();
for(int i = 0;i < bookshelf.getUsedSize();i++) {
System.out.println(books[i]);
}
}
}
找到了 | 没找到 |
---|---|
显示这本图书的基础信息以及借阅状态 | 提示操作者没找到 |
已被借出 | 未被借出 |
---|---|
提醒操作者 | 提醒操作者成功借出,并将该书籍的借阅状态改为已被借出(将isBorrowde改为true) |
代码如下:
public class Borrowing implements Operation {
@Override
public void work(Bookshelf bookshelf) {
Book[] books = bookshelf.getBooks();
System.out.println("请输入要借阅的书的书名");
Scanner scan = new Scanner(System.in);
String name = scan.nextLine();
boolean flag = false;
for(int i = 0;i < bookshelf.getUsedSize();i++) {
if(name.equals(books[i].getName())) {
System.out.println(books[i]);
if(books[i].isBorrowde() == false) {
books[i].setBorrowde(true);
System.out.println("成功借出" + name);
}
else{
System.out.println("此书已被借出");
}
break;
}
if(i == bookshelf.getUsedSize() - 1) {
System.out.println("查无此讯");
}
}
}
}
没有这本书 | 有这本书 |
---|---|
提醒操作者 | 提示操作者归还成功,并将该书籍借阅状态改为未被借出(将isBorrowde改为flase) |
代码如下:
public class Return implements Operation {
@Override
public void work(Bookshelf bookshelf) {
Book[] books = bookshelf.getBooks();
System.out.println("请依次要归还的书的书名");
Scanner scan = new Scanner(System.in);
String name = scan.nextLine();
for(int i = 0;i < bookshelf.getUsedSize();i++) {
if(name.equals(books[i].getName())) {
books[i].setBorrowde(false);
System.out.println("成功归还" + name);
}
else if(i == bookshelf.getUsedSize()) {
System.out.println("输入错误");
}
}
}
}
public class Exit implements Operation {
@Override
public void work(Bookshelf bookshelf) {
System.out.println("退出系统");
System.exit(0);
}
}
现在图书管理系统需要的各种功能的代码都已经写完了,
现在就需要整合了
这是普通用户视角
由这两张图可以看出,
用户选择完身份,就要弹出对应的菜单,
并且还要可以通过数字去选择各种功能,
所以咱们是不是可以创建一个功能数组,将用户输入的数字对应成下标然后去实现相应的功能;
下面咱们对之前代码进行改装;
代码如下:
public abstract class User {
protected String name;
Operation[] operations;
public User(String name) {
this.name = name;
}
public abstract int menu();
public void doWork(int choice, Bookshelf bookshelf){}
}
public class Administrator extends User{
public Administrator(String name) {
super(name);
this.operations = new Operation[]{new Exit(),
new Find(),
new NewPlus(),
new Delete(),
new DisPlay(),
};
}
//因为管理员要输入数字然后执行对应的操作,所以要返回一个整形
public 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 scan = new Scanner(System.in);
int choice = scan.nextInt();
return choice;
}
public void doWork(int choice1, Bookshelf bookshelf) {
operations[choice1].work(bookshelf);
}
}
public class RegularUsers extends User{
public RegularUsers(String name) {
super(name);
this.operations = new Operation[]{new Exit(),
new Find(),
new Borrowing(),
new Return()
};
}
//因为普通用户要输入数字然后执行对应的操作,所以要返回一个整形
public int menu() {
System.out.println("*************************");
System.out.println("欢迎 " + name + " 使用图书管理系统");
System.out.println(" 1.查找图书 ");
System.out.println(" 2.借阅图书 ");
System.out.println(" 3.归还图书 ");
System.out.println(" 0.退出系统 ");
System.out.println("*************************");
System.out.println("请输入要使用的操作");
Scanner scan = new Scanner(System.in);
int choice = scan.nextInt();
return choice;
}
public void doWork(int choice1, Bookshelf bookshelf) {
operations[choice1].work(bookshelf);
}
}
所有的功能都串联起来了,
下面就是实现图书管理系统的类的编写了
因为是要用户选择完身份就弹出对应的界面与可实现的功能
那么不如直接让这个静态方法的返回值就是这个身份
可能返回两种身份,普通用户与管理员,
所以可以直接让他向上转型成父类,
所以这个静态方法的返回值类型应该是 User
那么相应的if语句也要做出改变
public class Main {
private static User login() {
System.out.println("请输入姓名");
Scanner scan = new Scanner(System.in);
String name = scan.nextLine();
System.out.println("请选择身份 1-> 管理员,0->普通用户");
int choice = scan.nextInt();
if(choice == 1) {
//System.out.println("管理员登陆成功");
return new Administrator(name);
}
else {
//System.out.println("普通用户登陆成功");
return new RegularUsers(name);
}
}
接下来就是主函数了✌️
首先,一定是要先创建一个书架;
然后让一个User类型的变量去接收login这个静态方法的返回值,
操作是可以反复执行的,所以还需要写一个while语句
public static void main(String[] args) {
Bookshelf bookshelf = new Bookshelf();
User user = login();
while(true) {
}
}
已经用user去接收了身份,身份也已经衔接了操作功能,
所以只要重复的去接收user返回的整形,
并用user中的doWork方法去执行相应操作就ok了;
public static void main(String[] args) {
Bookshelf bookshelf = new Bookshelf();
User user = login();
while(true) {
int number = user.menu();
user.doWork(number,bookshelf);
}
}
实现图书管理系统的类的
代码如下:
public class Main {
private static User login() {
System.out.println("请输入姓名");
Scanner scan = new Scanner(System.in);
String name = scan.nextLine();
System.out.println("请选择身份 1-> 管理员,0->普通用户");
int choice = scan.nextInt();
if(choice == 1) {
return new Administrator(name);
}
else {
return new RegularUsers(name);
}
}
public static void main(String[] args) {
Bookshelf bookshelf = new Bookshelf();
User user = login();
while(true) {
int number = user.menu();
user.doWork(number,bookshelf);
}
}
}
至此整个图书管理系统就写完了;
仍有许多功能不够完善,
希望以后可以真正的写出一款有棱有角的我自己的软件;
加油啊各位!
至此本篇文章结束,
新手上路,有任何谬误,欢迎大家评论区批评指正
路漫漫,不止修身也养性