Java--圖書管理系統(簡易版)

目錄

目錄

前言

🔔1.library包

1.1 Book類

1.2 BookList類

🔔2.user包

2.1User類(父類)

2.2Admin(管理員)

2.3 NormalUser(普通用戶)

🔔3.Operation包

🕐3.1 IOperation接口

🕑3.2ListOperation(查看操作)

🕒3.3AddOperation(增加操作)

🕓3.4BorrowOperation(借書操作)

🕔3.5ReturnOperation(還書操作)

🕕3.6DelOperation(刪除操作)

🕖3.7FindOperation(查找操作)?

🕗3.8ExitOperation(退出操作)

🔔4.Main類

🔔5.效果展示


(ps:?在本篇文章中我們介紹了圖書管理系統📖,但是功能很少,所以在下一篇文章中,我又增加了幾個功能:大家可以點擊鏈接移步到下一篇文章(無講解的)

https://blog.csdn.net/2401_84024092/article/details/147874135?fromshare=blogdetail&sharetype=blogdetail&sharerId=147874135&sharerefer=PC&sharesource=2401_84024092&sharefrom=from_link

前言

🌈本篇文章會實現一個控制臺版本的“圖書管理系統”,涉及到 JavaSE中的繼承,多態,抽象類,接口。(代碼部分附有詳細的講解?)

在這個系統中:

1.能夠表示多本圖書的信息📘

2.提供兩種用戶:管理員普通用戶

3.普通用戶可以查看書籍列表查找圖書📖,借書,還書

4.管理員可以查看書籍列表,查找圖書📖,新增圖書,刪除圖書

整體框架如下:🎉

程序目錄如下:🎉

🔔1.library包

1.1 Book類

👉每本書📕都被定義為一個類,其中包含書名、作者、類型、價格和借閱狀態等屬性。這些屬性均被設置為private訪問權限,并通過getter和setter方法進行訪問和修改。在類的構造方法中,我們會對這些屬性進行初始化,其中借閱狀態默認設置為未借出(false)。

package library;
//一本書
public class Book {//現實世界的書private String name;private String author;private String type;private double price;private boolean isBorrowed;public Book(String name, String author, String type, double price){this.name=name;this.author=author;this.type=type;this.price=price;this.isBorrowed=false;}//alt+ins自動生成
//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 String getType() {return type;}public void setType(String type) {this.type = type;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}public boolean isBorrowed() {return isBorrowed;}public void setBorrowed(boolean borrowed) {isBorrowed = borrowed;}@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", author='" + author + '\'' +", type='" + type + '\'' +", price=" + price +", isBorrowed=" + (isBorrowed?"已借出":"未借出") +'}';}
}

1.2 BookList類

👉用來管理多個書籍對象

首先定義一個Book類類型的數組books,共分配1024個空間

?注意:我們約定好,所有有效的書籍,都是從0開始連續遞增排列的,以便可以通過size來描述有效書籍數目

package library;public class BookList {private Book[] books=new Book[1024];//此數組中每個類型都是Book類類型//長度不方便靈活調整,預先創造大空間//把booklist想象為一個書架,書架總共有1024個位置,不能修改大小,所以設置為private//長度不方便靈活調整,預先創造大空間private int size =0;//有效元素public BookList(){books[0]=new Book("西游記","吳承恩","古典小說",100);//books[0]中存放的是一組實例對象books[1]=new Book("紅樓夢","曹雪芹","古典小說",90);books[2]=new Book("高等數學","高斯","數學",40);books[3]=new Book("Java入門","詹姆斯高斯林","計算機",70);books[4]=new Book("紅樓夢","曹雪芹","古典小說",90);size=5;}public Book getBook(int index) {//得到序號為index的書籍return books[index];//不會越界,因為此時還沒滿}public void setBook(int index,Book book) {books[index] = book;}//將序號index處設置為××書public int getSize() {return size;//有效書籍數量}public void setSize(int size) {this.size = size;//設置有效書籍數量}
}

🔔2.user包

兩種用戶:普通用戶🙎?♀?+管理員👩?🏫

?注意:普通用戶與管理員的操作即存在重復的部分,也存在不同的部分,因此可以通過繼承,把相同的部分通過父類(User)提取出來

2.1User類(父類)

將抽象菜單方法(menu)定義在父類中,供子類重寫實現,并通過 IOperation[] 數組存儲管理員和用戶可執行的功能操作。

package library.user;import library.BookList;
import library.IOperation;public abstract class User {//不同 的用戶不同的操作protected String name;//各個子類都有的內容,直接放在父類中//protected子類可以直接獲取到,不必再去用getter setterprotected IOperation[] operations;//當前這個類能進行那些操作,就往這個數組里添加對應的對象public User(String name){this.name=name;}public abstract int menu();//不知道父類的菜單(父類就沒有菜單),我知道的只有管理員和用戶的菜單// 所以使用abstract,子類再進行重寫//為了避免父類被不小心創建出實例,所以要抽象(因為不能出現“父類菜單”)public void work(int choice, BookList bookList){//3.進入到父類的work方法if(choice<0||choice>=operations.length){System.out.println("輸入的選項非法");return;}operations[choice].work(bookList);//4.調用我選擇的方法里面的work方法,就能用此方法對booklist進行操作了}
}

2.2Admin(管理員)

🔔管理員應繼承父類User,通過重寫父類的 menu 方法,實現了自定義菜單功能,用戶可通過輸入選擇進入相應功能模塊。在子類構造函數中,首先調用父類構造方法完成名稱初始化,隨后對用戶操作進行配置(包括退出,查看,查找、新增、刪除的功能)。

注意:IOperation[]中的順序已經和菜單中的選項對應了

package library.user;import library.IOperation;
import library.Operation.*;import java.util.Scanner;public class Admin extends User{//private IOperation[] operations;//存放管理員的方法,這是什么類型呢,接口類型public Admin(String name) {super(name);operations=new IOperation[]{new ExitOperation(),new ListOperation(),new FindOperation(),new AddOperation(),new DelOperation(),};}@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;}
}

2.3 NormalUser(普通用戶)

🔔普通用戶應繼承父類User,通過重寫父類的 menu 方法,實現了自定義菜單功能,用戶可通過輸入選擇進入相應功能模塊。在子類構造函數中,首先調用父類構造方法完成名稱初始化,隨后對用戶操作進行配置(包括退出,查看,查找、借書、還書的功能)。

package library.user;import library.Operation.IOperation;
import library.Operation.*;import java.util.Scanner;public class NormalUser extends User {//private IOperation[] operations;public NormalUser(String name) {super(name);//對所要的方法進行初始化operations = new IOperation[]{//普通用戶進行的操作new ExitOperation(),//這是一個數組,此處下標為0new ListOperation(),new FindOperation(),new BorrowOperation(),new ReturnOperation(),};}@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;}
}

🔔3.Operation包

👓此包中包括所有需要進行的操作類

🔔🔔🔔看到這里我們發現,書籍和用戶并沒有建立起聯系,那么如何將BookList與用戶實現“交互”呢??

通過IOperation接口把用戶和書給關聯起來

🕐3.1 IOperation接口

增加這個接口后,所有的操作類都要實現自IOperation接口,并重寫其中的work方法,在每個操作類中的work方法的具體實現各不相同

?注意:這里有人可能會問:如果不設置接口,只在每個類中都寫上work方法,將參數BookList作為參數傳遞進去不就可以進行書籍與操作的聯系嗎,為什么還要設置接口呢

原因:簡單來說就是限制代碼的靈活性

解釋:理論上是可行的,但是不加接口的話,無法保證所有的類都提供了work方法,也沒法保證work方法的參數都是相同的。而加上后就能強制統一,方便后續的調用,否則如果大家提供的方法各不相同,就會顯得很亂。

package library.Operation;import library.BookList;public interface IOperation {//也可以使用抽象類,但是我這個接口我只想保存一些方法,并沒有什么實例屬性要繼承的//并且不能多繼承//而User中的類是抽象性,因為我們需要繼承name的屬性void work(BookList bookList);
}

🕑3.2ListOperation(查看操作)

?在每一次循環中都會創建一次book對象

?接著調用booklist中的getBook方法獲取到第i本書

當i為0時,創建的對象就是

Book book = new Book("西游記","吳承恩","古典小說",100);

最后實現打印操作,當打印book時,會自動調用Book類中的toString方法(打印格式可以自行調整)

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);//拿到第i本書System.out.println("["+i+"]"+book);}}
}

🕒3.3AddOperation(增加操作)

?讓用戶輸入新的書籍📕的信息,然后把這個新的書放到BookList

?這本新書存放到數組的最后一個位置上,在BookList中已經存在N本書了(size),這些書對應的下標[0,N-1],新的圖書📕就放到N的位置即可,在相應位置傳入書后,有效元素size也要加一

package library.Operation;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,type,price);int size=bookList.getSize();bookList.setBook(size,book);//傳入book就相當于傳入引用的空間bookList.setSize(size+1);//不能忘了修改sizeSystem.out.println("新增圖書完成!");}
}

🕓3.4BorrowOperation(借書操作)

?在借書操作時,要注意判斷是否被借出

package library.Operation;import library.Book;
import library.BookList;import java.util.Scanner;public class BorrowOperation implements IOperation {@Overridepublic void work(BookList bookList) {System.out.println("借書");Scanner scanner=new Scanner(System.in);System.out.println("請輸入要借閱的圖書編號:");int id= scanner.nextInt();if(id<0||id>=bookList.getSize()){System.out.println("輸入錯誤");return;}Book book=bookList.getBook(id);//獲取第id本書對象if(book.isBorrowed()){//先判斷一下是否被借出System.out.println("該書已經被借出了");//如果真就被借出了return;}book.setBorrowed(true);//沒借出我就可以借了System.out.println("借書成功!");}
}

🕔3.5ReturnOperation(還書操作)

?在借書操作時,也要注意判斷書是否已經被歸還了

package library.Operation;import library.Book;
import library.BookList;import java.util.Scanner;public class ReturnOperation implements IOperation {@Overridepublic void work(BookList bookList) {System.out.println("還書");Scanner scanner=new Scanner(System.in);System.out.println("請輸入要歸還的圖書編號:");int id= scanner.nextInt();if(id<0||id>=bookList.getSize()){System.out.println("輸入錯誤");return;}Book book=bookList.getBook(id);if(!book.isBorrowed()){//先判斷一下是否被借出falseSystem.out.println("該書沒借出,不能歸還");//如果沒被借出了,就不能換return;}book.setBorrowed(false);System.out.println("還書成功!");}
}

🕕3.6DelOperation(刪除操作)

?在進行刪除操作時,如果是最后一本書📕,直接將有效元素size-1即可

如果是中間位置元素,可以把最后一本書📕放在待刪除元素的位置上,然后再size-1即可。

package library.Operation;import library.Book;
import library.BookList;import java.util.Scanner;public class DelOperation implements IOperation {@Overridepublic void work(BookList bookList) {System.out.println("刪除書籍");Scanner scanner=new Scanner(System.in);System.out.println("請輸入要刪除書籍的序號:");int index=scanner.nextInt();if(index<0||index>=bookList.getSize()) {System.out.println("序號超出范圍");return;}if(index == bookList.getSize()-1){bookList.setSize(bookList.getSize()-1);//如果是最后一本書,直接將有效元素設置為size-1即可}else{//如果刪除中間元素,就可以把最后一個元素,復制到待刪除元素的位置上,然后size-1即可Book lastBook = bookList.getBook(bookList.getSize()-1);//先獲取到最后一本書bookList.setBook(index,lastBook);bookList.setSize(bookList.getSize()-1);}System.out.println("刪除書籍完成!");}
}

🕖3.7FindOperation(查找操作)?

?查找操作只需驗證輸入內容與書籍列表中的條目是否一致。

package library.Operation;import library.Book;
import library.BookList;import java.util.Scanner;public class FindOperation implements IOperation {@Overridepublic void work(BookList bookList) {System.out.println("查找操作");Scanner scanner=new Scanner(System.in);System.out.println("請輸入查找的書名");String name =scanner.next();for(int i=0;i<bookList.getSize();i++){Book book = bookList.getBook(i);if(book.getName().equals(name)){//比較字符串用這個System.out.println(book);}}System.out.println("查找完畢");}
}

🕗3.8ExitOperation(退出操作)

package library.Operation;import library.BookList;public class ExitOperation implements IOperation {@Overridepublic void work(BookList bookList) {System.out.println("goodbye!");System.exit(0);//退出整個程序}
}

🔔4.Main類

?在主類中根據用戶輸入跳轉到具體的用戶

package library;import library.user.NormalUser;
import library.user.User;
import library.user.Admin;
import java.util.Scanner;
public class Main {private static User login(){System.out.println("請輸入您的姓名:");Scanner scanner =new Scanner(System.in);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;}}public static void main(String[] args) {//書記管理library.BookList booklist=new BookList();//管理員和普通用戶讓用戶選擇User user = login();//User user=new NormalUser(name)//User user=new Admin(name)//向上轉型while(true){int choice = user.menu();//多態user.work(choice,booklist);//將選擇的菜單與書籍列表傳入,假如是查找,普通用戶}}
}

🔔5.效果展示

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/82575.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/82575.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/82575.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

深入淺出:Spring Boot 中 RestTemplate 的完整使用指南

在分布式系統開發中&#xff0c;服務間通信是常見需求。作為 Spring 框架的重要組件&#xff0c;RestTemplate 為開發者提供了簡潔優雅的 HTTP 客戶端解決方案。本文將從零開始講解 RestTemplate 的核心用法&#xff0c;并附贈真實地圖 API 對接案例。 一、環境準備 在 Spring…

大數據處理利器:Hadoop 入門指南

一、Hadoop 是什么&#xff1f;—— 分布式計算的基石 在大數據時代&#xff0c;處理海量數據需要強大的技術支撐&#xff0c;Hadoop 應運而生。Apache Hadoop 是一個開源的分布式計算框架&#xff0c;致力于為大規模數據集提供可靠、可擴展的分布式處理能力。其核心設計理念是…

685SJBH計量管理系統

摘 要 計量&#xff0c;在我國已有五千年的歷史。計量的發展與社會進步聯系在一起&#xff0c;它是人類文明的重要組成部分。它的發展經歷了古典階段、經典階段和現代階段。而企業的計量管理是對測量數據、測量過程和測量設備的管理。 本系統通過分析現有計量系統的業務邏輯…

從0到1構建前端監控系統:錯誤捕獲、性能采集、用戶體驗全鏈路追蹤實戰指南SDK實現

目錄 前言為什么要做前端監控前端監控目標穩定性用戶體驗業務 前端監控流程常見埋點方案代碼埋點可視化埋點無痕埋點 創建項目第一步、創建monitor文件&#xff0c;cmd進入文件進行npm init -y 項目初始化第二步、創建src/index.js和src/index.html文件第三步、創建webpack.con…

前端瀏覽器判斷設備類型的方法

前端瀏覽器判斷設備類型的方法 在前端開發中&#xff0c;判斷設備類型&#xff08;如手機、平板、桌面電腦&#xff09;有多種方法&#xff0c;以下是常用的幾種方式&#xff1a; 1. 使用 User Agent 檢測 通過 navigator.userAgent 獲取用戶代理字符串進行判斷&#xff1a;…

MNIST 手寫數字分類

轉自我的個人博客: https://shar-pen.github.io/2025/05/04/torch-distributed-series/1.MNIST/ 基礎的單卡訓練 本筆記本演示了訓練一個卷積神經網絡&#xff08;CNN&#xff09;來對 MNIST 數據集中的手寫數字進行分類的過程。工作流程包括&#xff1a; 數據準備&#xff…

數據庫中的 Segment、Extent、Page、Row 詳解

在關系型數據庫的底層存儲架構中&#xff0c;數據并不是隨意寫入磁盤&#xff0c;而是按照一定的結構分層管理的。理解這些存儲單位對于優化數據庫性能、理解 SQL 執行過程以及排查性能問題都具有重要意義。 我將從宏觀到微觀&#xff0c;依次介紹數據庫存儲中的四個核心概念&…

DAMA車輪圖

DAMA車輪圖是國際數據管理協會&#xff08;DAMA International&#xff09;提出的數據管理知識體系&#xff08;DMBOK&#xff09;的圖形化表示&#xff0c;它以車輪&#xff08;同心圓&#xff09;的形式展示了數據管理的核心領域及其相互關系。以下是基于用戶提供的關鍵詞對D…

《QDebug 2025年4月》

一、Qt Widgets 問題交流 1. 二、Qt Quick 問題交流 1.QML單例動態創建的對象&#xff0c;訪問外部id提示undefined 先定義一個窗口組件&#xff0c;打印外部的id&#xff1a; // MyWindow.qml import QtQuick 2.15 import QtQuick.Window 2.15Window {id: controlwidth: …

JS | 正則 · 常用正則表達式速查表

以下是前端開發中常用的正則表達式速查表&#xff0c;包含驗證規則、用途說明與示例&#xff1a; &#x1f4cc; 常用正則表達式速查表 名稱正則表達式描述 / 用途示例手機號/^1[3-9]\d{9}$/中國大陸手機號13812345678 ?座機號/^0\d{2,3}-?\d{7,8}$/固定電話010-12345678 ?…

系統思考:個人與團隊成長

四年前&#xff0c;我交付的系統思考項目&#xff0c;今天學員的反饋依然深深觸動了我。 我常常感嘆&#xff0c;系統思考不僅僅是一場培訓&#xff0c;更像是一場持續的“修煉”。在這條修煉之路上&#xff0c;最珍貴的&#xff0c;便是有志同道合的伙伴們一路同行&#xff0…

寫屏障和讀屏障的區別是什么?

寫屏障&#xff08;Write Barrier&#xff09;與讀屏障&#xff08;Read Barrier&#xff09;的區別 在計算機科學中&#xff0c;寫屏障和讀屏障是兩種關鍵的內存同步機制&#xff0c;主要用于解決并發編程中的可見性、有序性問題&#xff0c;或在垃圾回收&#xff08;GC&…

ssh -T git@github.com 測試失敗解決方案:修改hosts文件

問題描述 通過SSH方式測試&#xff0c;使用該方法測試連接可能會遇到連接超時、端口占用的情況&#xff0c;原因是因為DNS配置及其解析的問題 ssh -T gitgithub.com我們可以詳細看看建立 ssh 連接的過程中發生了什么&#xff0c;可以使用 ssh -v命令&#xff0c;-v表示 verbo…

大疆無人機搭載樹莓派進行目標旋轉檢測

環境部署 首先是環境創建&#xff0c;創建虛擬環境&#xff0c;名字叫 pengxiang python -m venv pengxiang隨后激活環境 source pengxiang/bin/activate接下來便是依賴包安裝過程了: pip install onnxruntime #推理框架 pip install fastapi uvicorn[standard] #網絡請求…

00 Ansible簡介和安裝

1. Ansible概述與基本概念 1.1. 什么是Ansible&#xff1f; Ansible 是一款用 Python 編寫的開源 IT 自動化工具&#xff0c;主要用于配置管理、軟件部署及高級工作流編排。它能夠簡化應用程序部署、系統更新等操作&#xff0c;并且支持自動化管理大規模的計算機系統。Ansibl…

Linxu實驗五——NFS服務器

一.NFS服務器介紹 NFS服務器&#xff08;Network File System&#xff09;是一種基于網絡的分布式文件系統協議&#xff0c;允許不同操作系統的主機通過網絡共享文件和目錄3。其核心作用在于實現跨平臺的資源透明訪問&#xff0c;例如在Linux和Unix系統之間共享靜態數據&#…

『 測試 』測試基礎

文章目錄 1. 調試與測試的區別2. 開發過程中的需求3. 開發模型3.1 軟件的生命周期3.2 瀑布模型3.2.1 瀑布模型的特點/缺點 3.3 螺旋模型3.3.1 螺旋模型的特點/缺點 3.4 增量模型與迭代模型3.5 敏捷模型3.5.1 Scrum模型3.5.2 敏捷模型中的測試 4 測試模型4.1 V模型4.2 W模型(雙V…

紅外遙控鍵

紅外 本章節旨在讓用戶自定義紅外遙控功能&#xff0c;需要有板載紅外接收的板卡。 12.1. 獲取紅外遙控鍵值 由于不同遙控器廠家定義的按鍵鍵值不一樣&#xff0c;所以配置不通用&#xff0c;需要獲取實際按鍵對應的鍵值。 1 2 3 4 5 6 #設置輸出等級 echo 7 4 1 7> /pr…

同一個虛擬環境中conda和pip安裝的文件存儲位置解析

文章目錄 存儲位置的基本區別conda安裝的包pip安裝的包 看似相同實則不同的機制實際路徑示例這種差異帶來的問題如何檢查包安裝來源最佳實踐建議 總結 存儲位置的基本區別 conda安裝的包 存儲在Anaconda(或Miniconda)目錄下的pkgs和envs子目錄中&#xff1a; ~/anaconda3/en…