前言
在我们系统学习完 类与对象、封装、继承、多态、抽象类、接口 六大面向对象核心知识点后,就已经正式踏入 Java OOP 编程的大门。理论学得多不如动手练一遍,本次我们通过简易控制台图书管理系统综合项目,把前面所有零散知识点全部串联起来,做到学以致用。项目全程分层架构清晰、代码规范、注释完整,完美贴合新手入门,理解完这个项目,面向对象基础就算真正吃透了。
一、前置知识回顾
本项目完整覆盖 Java 面向对象全部基础知识点,先快速回顾:
- 类与对象:类是事物的模板,对象是类的具体实例
- 封装:私有化类的成员属性,对外提供
get/set访问方法,隐藏内部数据、保证安全 - 继承:子类继承父类,复用父类属性与方法,使用
super关键字调用父类结构 - 多态:父类引用指向子类对象,同一行为不同对象表现出不同效果
- 抽象类:包含抽象方法,约束子类必须重写实现,无法创建对象
- 接口:仅定义功能规范,无方法体实现,用于统一标准、解耦代码
二、项目整体架构分层
本项目采用四层架构,结构清晰,低耦合易扩展,也是企业开发最基础的分层思想:
- 实体层(book 包):存放图书、书架数据,对应知识点:类、对象、封装
- 用户层(user 包):区分管理员、普通用户身份,对应知识点:抽象类、继承、多态
- 操作规范层(ioperations 包):定义所有图书操作统一接口,对应知识点:接口
- 主程序交互层:程序入口,负责登录、菜单循环、调用业务功能,串联整个系统
三、详细代码实现与讲解
3.1 实体层 book 包
负责存储所有数据,仅存放属性,不处理业务逻辑。
3.1.1 Book 图书实体类
封装单本图书信息:
书名、作者、价格、图书类型、借阅状态,属性私有化,重写 toString() 方便打印信息。
package book;
public class Book {
private String name;
private String author;
private double price;
private String type;
private boolean isBorrowed;
public Book(String name,String author,double 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 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;
}
@Override
public String toString() {
return "Book{"+"name="+name+",author="+author+",price="+price+",type="+type+","+(isBorrowed?"已借出":"未借出")+"}";
}
}
3.1.2 BookList 书架类
底层使用数组模拟书架容器,记录当前已存放图书数量,构造方法默认初始化三本图书,提供书架增删查改方法。
package book;
public class BookList {
private Book[] books=new Book[10];
private int usedSize;//书架中实际存放的图书数量
public Book getBooks(int pos) {
return books[pos];
}
public Book[] getBooks() {
return books;
}
public void setBooks( int pos,Book book) {
this.books[pos] =book;
}
public int getUsedSize() {
return usedSize;
}
public void setUsedSize(int usedSize) {
this.usedSize = usedSize;
}
public BookList(){
//初始化三本默认图书
this.books[0]=new Book("s0","0",10,"小说");
this.books[1]=new Book("s1","1",100,"小说");
this.books[2]=new Book("s2","2",1000,"小说");
this.usedSize=3;
}
}
3.2 用户层 user 包
抽象父类统一用户结构,派生出管理员和普通用户两个子类,
实现权限区分,完美体现继承、多态、抽象类。
3.2.1 User 抽象父类
抽象类,内置接口数组存储对应权限功能,定义抽象菜单方法,统一功能执行方法。
package user;
import book.BookList;
import ioperations.Ioperation;
public abstract class User {
protected String name;
public Ioperation[] ioperations;
public User(String name){
this.name=name;
}
//抽象菜单方法,强制子类重写
public abstract int menu();
//根据用户选择,执行对应功能
public void doIoperation(int choice, BookList bookList){
ioperations[choice].work(bookList);
}
}
3.2.2 AdminUser 管理员用户
继承抽象父类 User,拥有新增、删除、查找、展示图书全部管理权限。
package user;
import ioperations.*;
import java.util.Scanner;
public class AdminUser extends User{
public AdminUser(String name) {
super(name);
//初始化管理员权限功能数组
this.ioperations=new Ioperation[]{
new Exit(),
new Find(),
new Add(),
new Delate(),
new Show()
};
}
@Override
public int menu(){
System.out.println("欢迎"+this.name+"来到图书管理系统");
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("**********************");
Scanner scanner=new Scanner(System.in);
System.out.println("请输入你的操作:");
int choice=scanner.nextInt();
return choice;
}
}
3.2.3 NormalUser 普通用户
继承抽象父类 User,仅拥有查找、借阅、归还图书基础权限。
package user;
import ioperations.*;
import java.util.Scanner;
public class NormalUser extends User{
public NormalUser(String name) {
super(name);
//初始化普通用户权限功能数组
this.ioperations=new Ioperation[]{
new Exit(),
new Find(),
new Borrow(),
new Return()
};
}
@Override
public int menu(){
System.out.println("欢迎"+this.name+"来到图书管理系统");
System.out.println("*******普通用户菜单*******");
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);
System.out.println("请输入你的操作:");
int choice=scanner.nextInt();
return choice;
}
}
3.3 操作规范层 ioperations 包
3.3.1 Ioperation 功能接口
核心设计思想:面向接口编程
接口统一所有图书操作标准,所有业务功能类都实现该接口,仅需实现 work() 方法,后续新增功能只需新增实现类,无需改动原有代码,扩展性极强。
package ioperations;
import book.BookList;
public interface Ioperation {
void work(BookList bookList);
}
3.3.2 所有业务功能实现类
所有操作全部实现 Ioperation 接口,重写 work 方法完成具体业务逻辑。
Add 新增图书
package ioperations;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class Add implements Ioperation{
@Override
public void work(BookList bookList) {
int currentSize=bookList.getUsedSize();
//判断书架是否已满
if(currentSize== bookList.getBooks().length){
System.out.println("书架满了,不能放了");
return;
}
System.out.println("新添图书");
Scanner scanner=new Scanner(System.in);
System.out.println("请输入书名:");
String name=scanner.nextLine();
System.out.println("请输入作者:");
String author=scanner.nextLine();
System.out.println("请输入类型:");
String type=scanner.nextLine();
System.out.println("请输入价钱:");
double price=scanner.nextDouble();
Book newbook=new Book(name,author,price,type);
//判断图书是否重复
for(int i=0;i<currentSize;i++){
Book book=bookList.getBooks(i);
if(book.getName().equals(name)){
System.out.println("已经有了这本书,无法再次添加");
System.out.println(book);
return;
}
}
//添加图书
bookList.setBooks(currentSize,newbook);
bookList.setUsedSize(currentSize+1);
System.out.println("新增图书成功!");
}
}
Delate 删除图书
package ioperations;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class Delate 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 currentSize=bookList.getUsedSize();
int pos=-1;
int i=0;
//查找图书下标
for(;i<currentSize;i++){
Book book=bookList.getBooks(i);
if(book.getName().equals(name)){
System.out.println("找到了这本书:");
pos=i;
break;
}
}
if(i==currentSize){
System.out.println("没有你要删的图书");
return;
}
//数组元素前移完成删除
for(int j=pos;j<currentSize-1;j++){
Book book=bookList.getBooks(j+1);
bookList.setBooks(j,book);
}
bookList.setUsedSize(currentSize-1);
System.out.println("删除成功!");
}
}
Find 查找图书
package ioperations;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class Find 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 currentSize=bookList.getUsedSize();
for(int i=0;i<currentSize;i++){
Book book=bookList.getBooks(i);
if(book.getName().equals(name)){
System.out.println("找到了这本书:");
System.out.println(book);
return;
}
}
System.out.println("没有你要找的这本书");
}
}
Show 展示全部图书
package ioperations;
import book.Book;
import book.BookList;
public class Show implements Ioperation{
@Override
public void work(BookList bookList) {
System.out.println("显示图书");
int currentSize=bookList.getUsedSize();
for(int i=0;i<currentSize;i++){
Book book=bookList.getBooks(i);
System.out.println(book);
}
}
}
Borrow 借阅图书
package ioperations;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class Borrow 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 currentSize=bookList.getUsedSize();
for(int i=0;i<currentSize;i++){
Book book=bookList.getBooks(i);
if(book.getName().equals(name)){
if(book.isBorrowed()){
System.out.println("这本书已经被借出了");
return;
}
book.setBorrowed(true);
System.out.println("借阅成功!");
return;
}
}
System.out.println("没有找到你要借阅的这本书");
}
}
Return 归还图书
package ioperations;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class Return 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 currentSize=bookList.getUsedSize();
for(int i=0;i<currentSize;i++){
Book book=bookList.getBooks(i);
if(book.getName().equals(name)){
if(book.isBorrowed()){
book.setBorrowed(false);
System.out.println("归还图书成功!");
return;
}
}
}
System.out.println("没有你要归还的图书");
}
}
Exit 退出系统
package ioperations;
import book.BookList;
public class Exit implements Ioperation{
@Override
public void work(BookList bookList) {
System.out.println("退出系统");
System.exit(0);
}
}
3.4 程序入口 Main 类
系统总入口,实现用户登录、循环菜单调用,完整串联所有模块。
import book.BookList;
import user.User;
import java.util.Scanner;
public class Main {
//用户登录,体现多态:父类引用指向子类对象
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){
return new AdminUser(name);
}else{
return new NormalUser(name);
}
}
public static void main(String[] args) {
//1.创建书架对象
BookList bookList=new BookList();
//2.用户登录
User user = login();
//3.循环运行系统
while(true) {
//4.弹出菜单,用户选择操作
int choice = user.menu();
//5.执行对应功能
user.doIoperation(choice, bookList);
}
}
}
四、系统完整运行流程
新手最难理解的整体调用链路,全程四步循环运行:
-
初始化书架
BookList bookList=new BookList();程序启动创建书架容器,自动初始化三本默认图书。 -
用户登录
User user = login();输入姓名、选择身份,多态生效,父类引用接收管理员 / 普通用户子类对象。 -
菜单选择
int choice = user.menu();不同身份展示对应专属菜单,用户输入数字选择需要执行的操作。 -
执行业务功能
user.doIoperation(choice, bookList);
public void doIoperation(int choice, BookList bookList){
ioperations[choice].work(bookList);
}
用户在构造时已经将自身权限内的功能按菜单序号存入接口数组,根据输入下标取出对应功能对象,统一调用 work() 方法操作书架。
五、项目知识点总结
- 分层架构思想:数据存储、功能规范、用户权限、主程序入口完全分离,代码低耦合,结构清晰规范。
- 封装:图书属性私有化,保护数据不被随意修改,仅通过提供的方法访问。
- 继承与抽象类:抽象父类
User统一用户结构,子类继承扩展专属菜单。 - 多态:登录方法中父类引用指向不同子类,实现身份权限差异化。
- 接口:面向接口编程,统一操作标准,功能扩展方便,无需改动原有代码。
- 数组容器:底层使用数组模拟书架,完成图书增删查改基础操作。
- 权限区分设计:管理员拥有完整管理权限,普通用户仅开放借阅相关基础功能。
六、结语
这个控制台图书管理系统虽然简易,但是完整覆盖 Java 面向对象全部基础考点,是新手入门必练项目。从分层架构、接口设计、继承多态到封装,每一个知识点都有实际应用场景。建议大家手敲一遍代码,跟着流程走一遍调用逻辑,对面向对象的理解会有质的提升。
282

被折叠的 条评论
为什么被折叠?



