一.项目思路:
1.顾名思意,图书管理系统必须要有图书吧。那么就需要定义一个Book类。
2.顺着逻辑,那么书应该就应该放在书架上,因此也应该定义一个BookList类。
3.书架的功能是存放书籍、检查书籍是否被借阅、记录书籍的数量、添加、取出书籍等操作。
4.既然是图书管理系统,那么就会有管理员(AdminUser)和普通管理员(NormalUser)之分。
5.建立三个包,把相似行为的类存放到里面,便于查看。
6.最后在用Main这个类将它们结合起来,完成运行。
那么下面就进入项目:
二.定义框架
1.首先我们先定义Book类
public class Book {
private String name;
private float price;
private String author;
private String type;
private boolean islend;
public Book(String name,float price, String author, String type) {
this.name = name;
this.price = price;
this.author = author;
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
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 boolean isIslend() {
return islend;
}
public void setIslend(boolean islend) {
this.islend = islend;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", price=" + price +
", author='" + author + '\'' +
", type='" + type + '\'' +
", islend=" + islend +
'}';
}
}
这里教大家一个方法,在写好成员变量后,可以单击鼠标右键或者按照里面的快捷键,如图
然后
以及最后的toString方法
这样就完成了对Book类的定义,因为我们对于类的成员变量的保密性(private)所以要Getter and
Setter来对其进行获得与建立。
2.我们来定义书架BookList
1. 一个书架有许多本书嘛,所以我们采用以Book类型作为数组来定义,假设存放的是10本书(可以
根据自己的想法进行修改),即: Book[] books = new Book[10];
2.用usesized来记录已经已经存放的书籍。
3.用isFull来确实书架是否满了吗,满了的话意味着不能添加书籍进去了。
4.接着是建立构造方法对BookList的成员变量进行初始化。
package Library.book;
/**
* Created with IntelliJ IDEA.
* Description:
* User: king
* Date: 2024-03-10
* Time: 16:03
*/
public class BookList {//书架
private Book[] books = new Book[10];
private int usedsized;
public BookList(){
books[0] = new Book("三国演义", 12.0f, "罗贯中", "名著小说");
books[1] = new Book("红楼梦", 15.0f, "施耐庵", "名著小说");
books[2] = new Book("西游记", 19.0f, "吴承恩", "名著小说");
this.usedsized=3;
}
public Book getBook(int pos) {
return books[pos];
}
public void setBook(int pos,Book book) {
books[pos] = book;
}
public int getUsedsized() {
return usedsized;
}
public void setUsedsized(int usedsized) {
this.usedsized = usedsized;
}
public boolean isFull(){
if(this.usedsized==books.length){
return true;
}
return false;
}
}
3.使用者
普通用户和管理员一样都是人,有名字,有他们各自的菜单,既然都是使用者,不妨定义一个父类
User,是个抽象类。
public abstract class User {
protected String name;
public User(String name){
this.name=name;
}
public abstract int menu();
}
既然是个抽象类,那么子类继承之后也定要重写其抽象方法。
public class NormalUser extends User{//普通用户
public NormalUser(String name){
super(name);
};
}
public int menu(){
System.out.println("********普通用户菜单********");
System.out.println("******* 1.查找图书 ********");
System.out.println("******* 2.借阅图书 ********");
System.out.println("******* 3.归还图书 ********");
System.out.println("******* 0.退出系统 ********");
System.out.println("***************************");
System.out.print("请输入你的操作: ");
Scanner scanner = new Scanner(System.in);
int choice = scanner.nextInt();
return choice;
}
}
public class AdminUser extends User{//管理员用户
public AdminUser(String name){
super(name);
};
}
public int menu(){
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.print("请输入你的操作: ");
Scanner scanner = new Scanner(System.in);
int choice = scanner.nextInt();
return choice;
}
}
4.这个基本的框架就差不多搭好了,让我们在Main类结合起来看一下
package Library;
import Library.book.BookList;
import Library.user.AdminUser;
import Library.user.NormalUser;
import Library.user.User;
import java.util.Scanner;
public class Main {
public static User login(){
System.out.println("请输入你的名字");
Scanner scanner = new Scanner(System.in);
String name = scanner.next();
System.out.println("请输入你的身份 1.管理员 2.普通用户");
int identity = scanner.nextInt();
if(identity==1){
AdminUser adminUser = new AdminUser(name);
return adminUser;
}else{
NormalUser normalUser = new NormalUser(name);
return normalUser;
}
}
public static void main(String[] args) {
BookList bookList = new BookList();
//user 有可能引用 管理员用户 有可能引用 普通用户
User user = login();
while (true) {
int choice = user.menu();
}
}
}
那么在让我们对于书架上所发生的行为来进行细化。
三.细化框架
1.创建IOPeration这个接口
我们在书架上采取的记录书籍多少、增加书籍、取出书籍、查阅书籍、显示书籍,这些行为都是不
同的工作方式,所以我想创建一个接口,里面有个work方法,那么使用接口必须重写接口的方法。
注:以下如果涉及到遍历,是依赖于数组下标来实现的。在定义BookList说到书架是一个数组,0下标是一本书,1下标是一本书,以此类推。
package Library.operation;
import Library.book.BookList;
public interface IOPeration {
void work(BookList bookList);
}
又因为咱们是要对于书架中的书进行操作,而不是哪一具体本书,所以传参选择的是传书架。
2.添加书籍操作:AddOparetion
首先我们要添加书籍的一个前提条件是什么,是书架上有没有空位对不对,
这时我们前面写的检查满没满的函数就派上用场了。而且增加以后我们的书的数量要记得+1.
package Library.operation;
import Library.book.Book;
import Library.book.BookList;
import Library.user.AdminUser;
import java.util.Scanner;
public class AddOparetion implements IOPeration {
public void work(BookList bookList) {
System.out.println("新增图书");
if (bookList.isFull()) {
System.out.println("书架满了,不能再新增了!");
return;
}
System.out.println("请输入你要新增的书名:");
Scanner scanner = new Scanner(System.in);
String bookname = scanner.next();
System.out.println("请输入你要新增的图书的作者:");
String author = scanner.next();
System.out.println("请输入这本书的售价:");
float price = scanner.nextFloat();
System.out.println("请输入你这本书的类型:");
String type = scanner.next();
Book book = new Book(bookname,price,author,type);
int currently = bookList.getUsedsized();
bookList.setBook(currently,book);
bookList.setUsedsized(currently+1);
System.out.println("新增图书成功!");
}
}
3.添加借阅书籍操作:BorrowedOperation
这里的借阅并不是真正意义上的借出去了,而是通过对book这个类的成员方法setIslend传参来实现的。
package Library.operation;
import Library.book.Book;
import Library.book.BookList;
import java.util.Scanner;
public class BorrowedOperation implements IOPeration{
@Override
public void work(BookList bookList) {
System.out.println("借阅图书");
System.out.println(" 请你输入想要借阅的图书名");
Scanner scanner=new Scanner(System.in);
String bookname = scanner.next();
int currentsize = bookList.getUsedsized();
for (int i = 0; i < currentsize; i++) {
Book book = bookList.getBook(i);
if(bookname.equals(book.getName())){
book.setIslend(true);
System.out.println("借阅成功");
return;
}
}
System.out.println("借阅失败");
}
}
4.删除书籍操作:DelOperation
要注意的点有要先查找一下有没有你要删的书。如果有那么找到以后要记得把找到删除书籍后面的书都往前移,通过改变Book类的数组下标来实现
package Library.operation;
import Library.book.Book;
import Library.book.BookList;
import java.util.Scanner;
public class DelOperation implements IOPeration{
@Override
public void work(BookList bookList) {
System.out.println("删除图书");
System.out.println("请你输入要删除的图书");
Scanner scanner=new Scanner(System.in);
String bookname = scanner.next();
int currentsize = bookList.getUsedsized();
int pos=-1;
for (int i = 0; i < currentsize; i++) {
Book book = bookList.getBook(i);
if(book.getName().equals(bookname)){
pos=i;
break;
}
}
if(pos==-1){
System.out.println("没有你要删除的图书");
}else {
for (int j = pos; j <currentsize-1; j++) {
Book book = bookList.getBook(j+1);
bookList.setBook(j,book);
}
}
bookList.setUsedsized(currentsize-1);
System.out.println("删除成功!");
}
}
5.退出系统的操作:ExitOperation
这里采用的是把每本书都置为空的方法,很安全的方法。
package Library.operation;
import Library.book.Book;
import Library.book.BookList;
public class ExitOperation implements IOPeration{
@Override
public void work(BookList bookList) {
System.out.println("退出系统");
int currentsize = bookList.getUsedsized();
for (int i = 0; i < currentsize; i++) {
bookList.setBook(i,null);
}
System.exit(0);
}
}
6.查找书籍的操作:FindOperation
采用的是遍历的方法,一个一个与书名做比较。
package Library.operation;
import Library.book.Book;
import Library.book.BookList;
import java.util.Scanner;
public class FindOperation implements IOPeration{
@Override
public void work(BookList bookList) {
System.out.println("查阅书籍");
System.out.println("请输入你要查找的图书:");
Scanner scanner=new Scanner(System.in);
String bookname = scanner.next();
int currentsize = bookList.getUsedsized();
for (int i = 0; i < currentsize; i++) {
Book book = bookList.getBook(i);
if(book.getName().equals(bookname)){
System.out.println("找到了这本书:");
System.out.println(book);
return;
}
}
System.out.println("没有找到此书");
}
}
7.归还书籍:ReturnOperation
package Library.operation;
import Library.book.Book;
import Library.book.BookList;
import java.util.Scanner;
public class ReturnOperation implements IOPeration{
@Override
public void work(BookList bookList) {
System.out.println("归还书籍");
System.out.println("请输入你要归还的图书:");
Scanner scanner=new Scanner(System.in);
String bookname = scanner.next();
int currentsize = bookList.getUsedsized();
for (int i = 0; i < currentsize; i++) {
Book book = bookList.getBook(i);
if(book.getName().equals(bookname)){
book.setIslend(false);
System.out.println("归还成功");
return;
}
}
System.out.println("归还失败");
}
}
8.显示图书:ShowOperation
采用的是遍历打印的方式
package Library.operation;
import Library.book.Book;
import Library.book.BookList;
public class ShowOperation implements IOPeration{
@Override
public void work(BookList bookList) {
System.out.println("展示图书");
int currentsize = bookList.getUsedsized();
for (int i = 0; i < currentsize; i++) {
//Book book = bookList[i];
Book book = bookList.getBook(i);
System.out.println(book);
}
}
}
到了这里我们就基本写好了,就差最后的如何让管理员和普通用户实现了。
四.如何让这些类能够准确地被不同类型的用户使用
我们总不能一个if一个if语句去写吧,那样确实可以,但是我嫌太过麻烦。想一下,某一个不同行为
通过不同的人去做,发生的情况也会不同,这叫啥?
多态!在代码运行时,当传递不同类对象时,会调用对应类中的方法。
结合到我们上面的要求使用者输入对应的选项,比如用管理员举例,他有五个操作:
1.查找图书 2.新增图书 3. 删除图书 4.显示图书 0.退出系统
那么这五个类都有相同的接口,我们把这五个类都放在IOPeration类型的数组里面,此处把子类给
父类,会发生向上转型,以及动态绑定。即:
IOPeration[] ioPerations = new IOPeration[]{
new ExitOperation(),
new FindOperation(),
new AddOparetion(),
new DelOperation(),
new ShowOperation()
}
那么我们将它们分别放在各自的构造方法中
普通用户最终代码:
package Library.user;
import Library.operation.*;
import java.util.Scanner;
public class NormalUser extends User{
public NormalUser(String name){
super(name);
this.ioPerations = new IOPeration[]{
new ExitOperation(),
new FindOperation(),
new BorrowedOperation(),
new ReturnOperation()
};
}
public int menu(){
System.out.println("********普通用户菜单********");
System.out.println("******* 1.查找图书 ********");
System.out.println("******* 2.借阅图书 ********");
System.out.println("******* 3.归还图书 ********");
System.out.println("******* 0.退出系统 ********");
System.out.println("***************************");
System.out.print("请输入你的操作: ");
Scanner scanner = new Scanner(System.in);
int choice = scanner.nextInt();
return choice;
}
}
管理员最终代码:
package Library.user;
import Library.operation.*;
import java.util.Scanner;
public class AdminUser extends User{
public AdminUser(String name){
super(name);
this.ioPerations = new IOPeration[]{
new ExitOperation(),
new FindOperation(),
new AddOparetion(),
new DelOperation(),
new ShowOperation()
};
}
public int menu(){
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.print("请输入你的操作: ");
Scanner scanner = new Scanner(System.in);
int choice = scanner.nextInt();
return choice;
}
}
User最终代码:
public abstract class User {
protected String name;
protected IOPeration[] ioPerations;
public User(String name){
this.name=name;
}
public abstract int menu();
public void doIoperations(int choice, BookList bookList) {
this.ioPerations[choice].work(bookList);
}
}
Main最终代码:
package Library;
import Library.book.BookList;
import Library.user.AdminUser;
import Library.user.NormalUser;
import Library.user.User;
import java.util.Scanner;
public class Main {
public static User login(){
System.out.println("请输入你的名字");
Scanner scanner = new Scanner(System.in);
String name = scanner.next();
System.out.println("请输入你的身份 1.管理员 2.普通用户");
int identity = scanner.nextInt();
if(identity==1){
AdminUser adminUser = new AdminUser(name);
return adminUser;
}else{
NormalUser normalUser = new NormalUser(name);
return normalUser;
}
}
public static void main(String[] args) {
BookList bookList = new BookList();
//user 有可能引用 管理员用户 有可能引用 普通用户
User user = login();
while (true) {
int choice = user.menu();
//io[choice].work(书架);
user.doIoperations(choice, bookList);
}
}
}
五.对于这个项目的总结:
这个项目涉及了几乎所有的javaSE的语法,亲自动手有利于更深刻地理解语法,也是对于自己能
力得一种清楚地认识,比如较难懂的多态,一个不小心就可能错误,而且会发现很神奇。
在我看来掌握了语法不一定就会用了,要多多练习这种涵盖面广的项目。希望大家不要只停留在眼
睛上,手也要跟上,与君共勉。