文章目錄
-
- 前言
- 一、對象與功能剖析
- 二、代碼實作
-
- 2.1 Book包
-
- 2.1.1 書籍類(Book)
- 2.1.2 書架類(BookList)
- 2.2 Users 包
-
- 2.2.1 使用者類(User)
- 2.2.2 普通使用者類(NormalUser)
- 2.2.3 圖書管理者類(Administrator)
- 2.3 Function 包
-
- 2.3.1 IFunction 接口
- 2.3.2 查找書籍(FindFunction)
- 2.3.3 增加書籍 (AddFunction)
- 2.3.4 删除書籍(DelFunction)
- 2.3.5 列印書籍(DisplayFunction)
- 2.3.6 整理書籍(SortFunction)
- 2.3.7 借閱書籍(BorrowFunction)
- 2.3.8 歸還書籍(ReturnFunction)
- 2.3.9 退出系統(ExitFUnction)
- 2.4 Main類
- 三、項目總結
前言
在前面的幾節部落格中,山居向大家剖析了類和對象,介紹了包,詳析了面向對象的基本特征,生動講解了什麼是接口,總結的過程中,收益匪淺。
此次,山居将容這些東西于一體,寫一個
Java 圖書管理系統

通通都沒有!(不是)。。。
該圖書館管理系統隻是為了總結之前所學,将其投入應用當中,不整太進階的,隻為融會貫通,菜鳥版圖書管理系統,菜鳥值得擁有!
一、對象與功能剖析
面向對象程式設計首先需要明白對象都有哪些
建立一個圖書管理圖書系統應該有的大體對象有:
圖書
,
使用者
以及
管理系統的各種功能
關于圖書
需要一個類(Book)包含圖書的各項資訊
需要一個書架,将書(Book)放在其中
關于使用者
普通使用者
圖書管理者
關于功能(對于不同的使用者實作的功能有所不同)
普通使用者:圖書管理者:
- 查找書籍
- 借閱書籍
- 歸還書籍
- 退出系統
- 查找書籍
- 增加書籍
- 删除書籍
- 列印書籍
- 整理書籍
- 退出系統
所有的功能都是針對
BookList
類展開的,為了将各種方法聯系在一起,需要功能們都實作接口
IFunction
,重寫該接口中的抽象方法。
最後還需要一個
Main
類将上面的類、各種資訊串通在一起
二、代碼實作
此次的項目一共建立了三個包來裝類
- Book 包:裝圖書相關類
- Users 包:裝使用者類
- Function 包:裝功能類
2.1 Book包
2.1.1 書籍類(Book)
- 書籍資訊包括
、
書名
、
作者
以及
價格
(為了安全性,實作封裝,書籍資訊用 private 關鍵字修飾)
是否被借出
- 提供書籍資訊的
方法(alt + insert -> Getter and Setter),使外界可以擷取書的資訊
Getter and Setter
- 提供書籍類含有書名、作者、價格的三個參數的
(借出狀态是一種狀态,無需傳參)
構造方法
(alt + insert -> toString()),可以做适當的修改,例如借出狀态預設為 false(列印未借出),當書被借出,其狀态為 true (列印已借出)
重寫 toString 方法
package Book;
public class Book {
//書籍相關資訊
private String name;
private String author;
private Double price;
private Boolean isBorrow = false ;
//書籍資訊的 Getter and Setter 方法
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 Boolean getBorrow() {
return isBorrow;
}
public void setBorrow(Boolean borrow) {
isBorrow = borrow;
}
public Book(String name, String author, Double price) {
this.name = name;
this.author = author;
this.price = price;
}
//重寫 toString 方法
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
", isBorrow=" + ((isBorrow)?"已借出":"未借出") +
'}';
}
}
注意:
在 Java 中也有 Book類,而我們需要使用的我們自定義的 Book 類,在執行個體>化的時候需要導入正确的包(import Book.Book;),否則會報錯
2.1.2 書架類(BookList)
- 書架中包含書本的數目(
)和各種 Book 類型的書(創造Book類型的 books 數組)
bookCount
- 提供 BookList 類的無參的構造方法來
(在這裡放了三本書),書本的數目(bookCount)為3
初始化 books 數組
- 提供
方法,傳回 books 數組中下标為 i 的書籍,例如列印書籍功能就需要該方法通路到每本書籍
returnBook
- 提供
方法,在books 數組中下标為 num 的位置放置書籍,例如增加書籍功能中就需要在周遊完 books 數組來确認書架上沒有想要增加的書的情況下,在下标為 bookCount 的位置放置新增加的書
setBooks
- 提供
方法,使外界擷取書本的數目
getBookCount
- 提供
方法,使外界可以改變書本的數目,例如删除書籍功能中就需要在周遊完 books 數組來确認書架上有想要删除的書的情況下,将書籍删除,通過該方法将書本數目減一
setBookCount
package Book;
public class BookList {
private int bookCount;
public Book[] books = new Book[20];
public BookList() {
books[0] = new Book("Java","C張三",32.8);
books[1] = new Book("C++","B李四",59.0);
books[2] = new Book("Python","A王五",29.8);
this.bookCount = 3;
}
//傳回在i下标處的書本
public Book returnBook(int i) {
return books[i];
}
//在num位置放置一本書
public void setBooks(Book book,int num) {
books[num] = book;
}
//傳回此時書本的本數
public int getBookCount() {
return bookCount;
}
//改變書本的數目
public void setBookCount(int bookCount) {
this.bookCount = bookCount;
}
}
2.2 Users 包
無論是還是
普通使用者
都共同屬于
圖書管理者
戶,是以他們共同的資訊就可以寫在使用者類中,來
用
使用者類,進而達到代碼的重用
繼承
2.2.1 使用者類(User)
- 使用者都擁有的變量是使用者名字
- 提供使用者類含有一個參數(name)的構造方法
- 提供抽象方法
,因為普通使用者和圖書管理者的菜單是不同的,重寫 menu,當發生向上轉型的時候,通過重寫的 menu 可以通路到不同類型的使用者的菜單,實作了多态
menu
- 該類中還包含着
(接口)類型的數組
IFunction
,因為不同類型的使用者可以實作的功能是不同的,可以在子類幫父類進行構造方法的構造時定義不同内容的 iFunctions
iFunctions
- 提供
方法,對 bookList(通過 BookList 類執行個體化的對象即書架) 實作 iFunctions 數組下标為 choice 的功能
getFunction
package Users;
import Book.BookList;
import Function.IFunction;
public abstract class User {
//使用者姓名
protected String name;
//該數組可以接收不同類型使用者的功能
protected IFunction[] iFunctions;
//構造方法
public User(String name) {
this.name = name;
}
//需要被重寫以達到多态,拿到不同菜單的抽象方法 menu
public abstract int menu();
//choice 表示iFunctions數組的下标,choice 不同,實作的功能不同
public void getFunction(int choice,BookList bookList) {
this.iFunctions[choice].work(bookList);
}
}
2.2.2 普通使用者類(NormalUser)
- 普通使用者類繼承了使用者類,幫父類進行構造的時候初始化父類的 iFunctions 的數組
- 重寫父類的抽象方法 menu
package Users;
import Function.*;
import java.util.Scanner;
public class NormalUser extends User{
public NormalUser(String name) {
super(name);
//初始化父類的 iFunctions 的數組
iFunctions = new IFunction[]{
new ExitFunction(),
new FindFunction(),
new BorrowFunction(),
new ReturnFuntion()
};
}
// 重寫父類的抽象方法 menu
@Override
public int menu() {
System.out.println("=========普通使用者菜單==========");
System.out.println("Hello " + this.name + " 歡迎來到圖書管理系統");
System.out.println("1.查找書籍");
System.out.println("2.借閱書籍");
System.out.println("3.歸還書籍");
System.out.println("0.退出系統");
System.out.println("請選擇你想要進行的操作");
Scanner scanner = new Scanner(System.in);
while (true) {
int choice = scanner.nextInt();
if (choice >= 0 && choice <= 3) {
return choice;
} else {
System.out.println("選擇錯誤,請重新選擇!");
}
}
}
}
2.2.3 圖書管理者類(Administrator)
和普通使用者類方法一樣
package Users;
import Function.*;
import java.util.Scanner;
public class Administrator extends User{
public Administrator(String name) {
super(name);
//初始化父類的 iFunctions 的數組
iFunctions = new IFunction[] {
new ExitFunction(),
new FindFunction(),
new AddFunction(),
new DelFunction(),
new DisplayFunction(),
new SortFunction()
};
}
// 重寫父類的抽象方法 menu
@Override
public int menu() {
System.out.println("=========圖書管理者菜單==========");
System.out.println("Hello " + this.name + " 歡迎來到圖書管理系統");
System.out.println("1.查找書籍");
System.out.println("2.增加書籍");
System.out.println("3.删除書籍");
System.out.println("4.列印書籍");
System.out.println("5.整理書籍");
System.out.println("0.退出系統");
System.out.println("請選擇你想要進行的操作");
Scanner scanner = new Scanner(System.in);
while (true) {
int choice = scanner.nextInt();
if (choice >= 0 && choice <= 5) {
return choice;
} else {
System.out.println("選擇錯誤,請重新選擇!");
}
}
}
}
2.3 Function 包
實際上功能往往是放在最後完成的,除了功能以外的部分就是整個項目的架構,完成了架構後,再來實作功能就很簡單了。
2.3.1 IFunction 接口
實作接口 IFunction
package Function;
import Book.BookList;
public interface IFunction {
void work(BookList bookList);
}
2.3.2 查找書籍(FindFunction)
周遊 bookList 檢視是否有想要查找的書籍
package Function;
import Book.BookList;
import java.util.Scanner;
public class FindFunction implements IFunction{
@Override
public void work(BookList bookList) {
System.out.println("請輸入你想要查找的書籍:");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
int num = bookList.getBookCount();
for (int i = 0; i < num; i++) {
if (name.equals(bookList.returnBook(i).getName())) {
System.out.println(bookList.returnBook(i));
System.out.println("查找成功!");
return;
}
}
System.out.println("不存在這本書!");
}
}
2.3.3 增加書籍 (AddFunction)
- 重寫接口中的 work 方法
- 周遊 bookList 裡的所有書,當不存在該書時,就執行個體化一本書,通過 setBooks 方法将書放到書架上,通過 setBookCount 方法使書本數目加一
package Function;
import Book.Book;
import Book.BookList;
import java.util.Scanner;
public class AddFunction implements IFunction{
@Override
public void work(BookList bookList) {
System.out.println("想要添加的書籍的名字:");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
int num = bookList.getBookCount();
for (int i = 0; i < num; i++) {
if (name.equals(bookList.returnBook(i).getName())) {
System.out.println("已經存在該本書!");
return;
}
}
System.out.println("書籍的作者:");
String author = scanner.nextLine();
System.out.println("書籍的價格:");
Double price = scanner.nextDouble();
Book book = new Book(name,author,price);
bookList.setBooks(book,num);
bookList.setBookCount(num + 1);
System.out.println("增加成功!");
}
}
2.3.4 删除書籍(DelFunction)
- 總體思想和增加一本書差不多
- 當在 bookList 中找到想要删除的書籍時(例如書籍所在的下标為 i ),那麼就得到下标為 i + 1 的書籍使之覆寫下标為 i 處的書籍,i ++ ,切記
,否則會通路到非書籍的部分(越界)
i 的值一定要小于書本的數目減一
- 删除成功後一定要記得将書本的數目減一
package Function;
import Book.BookList;
import java.util.Scanner;
public class DelFunction implements IFunction{
@Override
public void work(BookList bookList) {
System.out.println("請輸入你想要删除的書籍:");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
int num = bookList.getBookCount();
for (int i = 0; i < num; i++) {
if (name.equals(bookList.returnBook(i).getName())) {
for (int j = i; j < num - 1; j++) {
bookList.setBooks(bookList.returnBook(j + 1),j);
}
System.out.println("删除成功!");
bookList.setBookCount(num - 1);
return;
}
}
System.out.println("不存在這本書!");
}
}
2.3.5 列印書籍(DisplayFunction)
package Function;
import Book.BookList;
public class DisplayFunction implements IFunction{
@Override
public void work(BookList bookList) {
int num = bookList.getBookCount();
for (int i = 0; i < num; i++) {
System.out.println(bookList.returnBook(i));
}
}
}
2.3.6 整理書籍(SortFunction)
- 整理書籍即對 BookList 上的書籍以自己的想要的标準進行排序,這裡就用到了
接口,具體用法在生動例子詳解接口這一小節中有所介紹,這裡就不多言
Comparator
- 在
類中定義一個 Comparator 接口類型的數組 comparators,通過該數組來選擇比較器
SortFunction
package Function;
import Book.Book;
import Book.BookList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
class NameComparator implements Comparator<Book> {
@Override
public int compare(Book o1, Book o2) {
return o1.getName().compareTo(o2.getName());
}
}
class AuthorComparator implements Comparator<Book> {
@Override
public int compare(Book o1, Book o2) {
return o1.getAuthor().compareTo(o2.getAuthor());
}
}
class PriceComparator implements Comparator<Book> {
@Override
public int compare(Book o1, Book o2) {
return (int)(o1.getPrice()-o2.getPrice());
}
}
public class SortFunction implements IFunction{
public Book[] array(Book[] book,int num) {
Book[] books = new Book[num];
for (int i = 0; i < num; i++) {
books[i] = new Book(book[i].getName(),book[i].getAuthor(),book[i].getPrice());
}
return books;
}
@Override
public void work(BookList bookList) {
Scanner scanner = new Scanner(System.in);
Comparator[] comparators = new Comparator[] {
new NameComparator(),
new AuthorComparator(),
new PriceComparator()
};
while (true) {
System.out.println("請問想要以什麼标準進行排序:0.name 1.author 2.price 3.isBorrow");
int choice = scanner.nextInt();
if (choice >= 0 && choice <= 2 ) {
Book[] newBooks = array(bookList.books,bookList.getBookCount());
Arrays.sort(newBooks, comparators[choice]);
for (int i = 0; i < newBooks.length; i++) {
System.out.println(newBooks[i]);
}
System.out.println("排序完成!");
return;
}else {
System.out.println("選擇錯誤!");
}
}
}
}
注意:
參數一是需要進行
Arrays.sort(參數一,參數二);
,參數二是使用到的
排序的對象
比較器
- 切記!!不可以将 bookList 裡的 books 直接傳到參數一中,因為 books 中可以放20本書,但是真正初始化的卻不足20本(例如該數組中最初隻有3本書,那麼剩下17個未初始化的下标的内容全是null),用比較器就會發生空指針異常
- 是以可以通過 array 方法來擷取到 books 中真正被初始化的内容
山居因為大意了,在此坑中躺了蠻久。。。
2.3.7 借閱書籍(BorrowFunction)
思路大同小異,周遊 bookList 中的書,借閱即将找到的那本書的借閱狀态改為 true,如果該書的借閱狀态在借之前就是 true ,說明該書已經被借走了
package Function;
import Book.BookList;
import java.util.Scanner;
public class BorrowFunction implements IFunction{
@Override
public void work(BookList bookList) {
System.out.println("請輸入你想要借閱的書籍:");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
int num = bookList.getBookCount();
for (int i = 0; i < num; i++) {
if (name.equals(bookList.returnBook(i).getName())) {
if (bookList.returnBook(i).getBorrow()) {
System.out.println("該書已被借閱");
return;
}
bookList.returnBook(i).setBorrow(true);
System.out.println("借閱成功!");
return;
}
}
System.out.println("不存在這本書!");
}
}
2.3.8 歸還書籍(ReturnFunction)
歸還思路與借閱同
package Function;
import Book.BookList;
import java.util.Scanner;
public class ReturnFuntion implements IFunction{
@Override
public void work(BookList bookList) {
System.out.println("請輸入你想要歸還的書籍:");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
int num = bookList.getBookCount();
for (int i = 0; i < num; i++) {
if (name.equals(bookList.returnBook(i).getName())) {
if (!bookList.returnBook(i).getBorrow()) {
System.out.println("未借閱過此書");
return;
}
bookList.returnBook(i).setBorrow(false);
System.out.println("歸還成功!");
return;
}
}
System.out.println("不存在這本書!");
}
}
2.3.9 退出系統(ExitFUnction)
當從鍵盤中讀入一個0時成功退出系統
package Function;
import Book.BookList;
public class ExitFunction implements IFunction{
@Override
public void work(BookList bookList) {
System.out.println("成功退出系統!");
System.exit(0);
}
}
2.4 Main類
- 執行個體化一個 BookList 類的對象,創造一個書架 bookList
- 提供 login 方法,該方法中通過不同的選擇傳回不同的結果,發生向上轉型,使 user 通路到不同的菜單
- 通過菜單進行選擇功能,傳回的值傳入 getFunction 方法中,擷取不同的功能
import Book.BookList;
import Users.Administrator;
import Users.NormalUser;
import Users.User;
import java.util.Scanner;
public class Main {
public static User login() {
System.out.println("請輸入你的姓名:");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
System.out.println("請選擇你的身份:1=》管理者 0=》普通使用者");
while (true) {
int choice = scanner.nextInt();
if (choice == 1) {
return new Administrator(name);
}else if (choice == 0) {
return new NormalUser(name);
}else {
System.out.println("選擇錯誤,請重新輸入!");
}
}
}
public static void main(String[] args) {
BookList bookList = new BookList();
User user = login();
while (true) {
int choice = user.menu();
user.getFunction(choice,bookList);
}
}
}
講到這兒,一切聯系了起來。。。。
三、項目總結
沒啥好總結的,我知道的内容都老實交代了,沒明白的大兄弟,咱再看一遍。。。
或者來複習複習
【Java】剖析類和對象
【Java】包與繼承
【Java】多态與抽象類
【Java】生動例子詳解接口
散了散了。。。。。。