JavaSE语法巩固——图书管理系统
之前为大家分享了Java的大部分基础语法,这次跟随博主来巩固一下学习内容吧!
本篇技术博客,将为大家分享一个图书管理系统小项目及作为一个面向对象编程的初学者,我的学习心得。
文章目录
- 一、项目效果展示
- 二、代码实现
- 构造对象思想
- 写在项目之前
- book包
- Book.java
- Booklist.java
- ioperations包
- IOperation.java
- AddOperation.java
- DelOperation.java
- FindOperation.java
- ShowOperation.java
- BorrowOperation.java
- ReturnOperation.java
- ExitOperation.java
- user包
- User.java
- NormalUser.java
- AdminUser.java
- Main.java
- 在实践中加深了抽象类、接口设计的理解
一、项目效果展示


二、代码实现
本次项目共分为三个包:book、ioperations、user,分别管理书籍相关类、用户操作相关实现类、封装用户的类。
构造对象思想
-
对象的核心是“抽象的封装体”:实物对象是面向对象编程(OOP)的入门案例,而非全部。非实物对象的设计更能体现OOP的灵活性,是复杂系统中实现业务解耦、逻辑复用的关键。判断一个概念能否作为对象,核心看其是否具备“可抽象的属性”和“可封装的行为”,而非是否为实物。
-
面向对象编程,讲究的就是创建对象,完成交互。当我们终于搞明白了要创建哪些对象,但有可能在定义类时还有点不太清楚类中都应该构建哪些东西。这时可以想一想程序运行时创建了这个对象,然后是要调用对象中的方法来完成交互的的。那我们是要它做些什么?这个阶段关于这个对象会发生什么?这些事情也就是我们要在类中定义的行为(方法)。
写在项目之前
-
我们在完成一个项目时,除了之前贪吃蛇的总结,我觉得还是要有清晰的框架意识。不要上来就着急敲,先把架构搭建好,具体逻辑功能实现可以先简单输出下意图,这些都是再一个一个实现就行(除非是核心业务逻辑,不可忽略)。
-
在设计方法时不要总是盯着当前类看,要多思考该方法被谁调用?被调用时的场景是什么?以此来设计方法逻辑。
book包
Book.java
定义一个书籍类,封装书籍的各种信息
package book;public class Book {//书的各属性private String name;private String author;private int price;private String type;private boolean isBorrowrd;public Book(String name, String author, int 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 int getPrice() {return price;}public void setPrice(int price) {this.price = price;}public String getType() {return type;}public void setType(String type) {this.type = type;}public boolean isBorrowrd() {return isBorrowrd;}public void setBorrowrd(boolean borrowrd) {isBorrowrd = borrowrd;}//重写toString方法,以便展示图书@Overridepublic String toString() {return "Book{" +"书名:'" + name + '\'' +", 作者:'" + author + '\'' +", 价格:" + price +", 类型:'" + type + '\'' +(isBorrowrd?",已借出":",未借出" )+'}';}
}
Booklist.java
定义书架类,管理多本书籍,构建起系统的信息库
package book;public class BookList {private Book[] books=new Book[10];//给个数组(书架),总大小为10本书private int bookNum;//实际书架上在记录的书籍数量//先放三本书public BookList() {//初始化先放三本书this.books[0] =new Book("三国演义","罗贯中",11,"小说") ;this.books[1] =new Book("西游记","吴承恩",12,"小说") ;this.books[2] =new Book("红楼梦","曹雪芹",13,"小说") ;this.bookNum=3;}public Book[] getBooks() {return books; //使用书架}public int getBookNum() {return bookNum;}public void setBookNum(int bookNum) {this.bookNum = bookNum;}public Book getBook(int pos) {return books[pos]; //返回单本书籍}public void setBook(int pos,Book book) {this.books[pos]=book; //在书架的 pos 位置放上一本书}
}
ioperations包
IOperation.java
定义操作接口,以后进行图书操作、管理都要实现这个接口
package ioperations;import book.BookList;//定义操作接口,以后进行图书操作、管理都要实现这个接口
//也方便用接口来接收不同实现类的对象,以便对这些不同类的对象进行统一管理、使用
public interface IOperation {void work(BookList bookList);//实现类实现了接口,得到了书架(booklist),可以对书籍进行各种操作
}
//那么在ioperations包中创建操作类实现此接口,定义自己对象的行为
下面开始定义IOperation接口的实现类,设计各个操作的功能
AddOperation.java
添加图书操作
package ioperations;import book.Book;
import book.BookList;import java.util.Scanner;public class AddOperation implements IOperation{@Overridepublic void work(BookList bookList) {System.out.println("添加图书....");//判断书架满没满if(bookList.getBookNum()==bookList.getBooks().length){System.out.println("书架已经满了!");return;}//输入书籍信息、构建对象Scanner scanner = new Scanner(System.in);System.out.println("请输入书名:");String name = scanner.nextLine();//先检查一下书架上是不是已经有了这本书//遍历int bookNum=bookList.getBookNum();for (int i = 0; i <bookNum ; i++) {Book curBook=bookList.getBook(i);if(curBook.getName().equals(name)){System.out.println("书架上已经有《"+name+"》啦!");return;}}System.out.println("请输入作者:");String author = scanner.nextLine();System.out.println("请输入书的类型:");String type = scanner.nextLine();System.out.println("请输入价格:");int price = scanner.nextInt();Book newbook=new Book(name,author,price,type);//放入书籍bookList.setBook(bookNum,newbook);bookList.setBookNum(bookNum+1);System.out.println("《"+name+"》添加成功");}
}
DelOperation.java
删除图书操作
package ioperations;import book.Book;
import book.BookList;import java.util.Scanner;public class DelOperation implements IOperation{@Overridepublic void work(BookList bookList) {System.out.println("删除图书....");System.out.println("请输入您要删除的书籍名字:");Scanner sc=new Scanner(System.in);String name=sc.nextLine();//找一下有没有这本书int bookNum=bookList.getBookNum();int i = 0;for (; i <bookNum ; i++) {Book curBook=bookList.getBook(i);if(curBook.getName().equals(name)){break;}}if(i==bookNum){System.out.println("并没有您想要删除的书...");return;}//删除图书//直接从最后开始后一个图书信息覆盖前一个图书,直到i位置for (int j = i; j <bookNum-1 ; j++) {Book book=bookList.getBook(j+1);bookList.setBook(j,book);}bookList.setBookNum(bookNum-1);System.out.println("《"+name+"》删除成功!");}
}
FindOperation.java
查找图书操作
package ioperations;import book.Book;
import book.BookList;import java.util.Scanner;public class FindOperation implements IOperation{@Overridepublic void work(BookList bookList) {System.out.println("查找图书....");Scanner sc=new Scanner(System.in);System.out.println("请输入您要查找的书籍名字:");String name = sc.nextLine();//查找int bookNum=bookList.getBookNum();int i = 0;for (; i <bookNum ; i++) {Book curBook=bookList.getBook(i);if(curBook.getName().equals(name)){Book book=bookList.getBook(i);System.out.println("找到啦!\n一下为书籍信息:");System.out.println(book);return;}}System.out.println("并没有您要找的书...");}
}
ShowOperation.java
展示书架上的所有图书
package ioperations;import book.Book;
import book.BookList;public class ShowOperation implements IOperation{@Overridepublic void work(BookList bookList) {System.out.println("展示图书....");int currentSize = bookList.getBookNum();//3for (int i = 0; i < currentSize; i++) {Book book = bookList.getBook(i);System.out.println(book);}}
}
BorrowOperation.java
借阅图书操作
package ioperations;import book.Book;
import book.BookList;import java.util.Scanner;public class BorrowOperation implements IOperation{@Overridepublic void work(BookList bookList) {System.out.println("借阅书籍....");System.out.println("请输入您要借阅的书籍名字:");Scanner sc=new Scanner(System.in);String name=sc.nextLine();//查找int bookNum=bookList.getBookNum();int i = 0;for (; i <bookNum ; i++) {Book curBook=bookList.getBook(i);if(curBook.getName().equals(name)){Book book=bookList.getBook(i);if(book.isBorrowrd()){System.out.println("很抱歉,《"+name+"》已经被借出了!");return;}else{bookList.getBook(i).setBorrowrd(true);System.out.println("借阅成功!");return;}}}System.out.println("并没有您要找的书...");}
}
ReturnOperation.java
归还图书操作
package ioperations;import book.Book;
import book.BookList;import java.util.Scanner;public class ReturnOperation implements IOperation{@Overridepublic void work(BookList bookList) {System.out.println("归还书籍....");System.out.println("请输入您要归还的书籍名字:");Scanner sc=new Scanner(System.in);String name=sc.nextLine();//查找int bookNum=bookList.getBookNum();int i = 0;for (; i <bookNum ; i++) {Book curBook=bookList.getBook(i);if(curBook.getName().equals(name)){bookList.getBook(i).setBorrowrd(true);System.out.println("归还成功!");return;}}System.out.println("很抱歉,该图书馆并未借出过此书!");}
}
ExitOperation.java
退出程序操作
package ioperations;import book.BookList;public class ExitOperation implements IOperation{@Overridepublic void work(BookList bookList) {System.out.println("退出程序....");System.exit(0);}
}
user包
User.java
定义一个父类,将不同用户的共性抽取出来,后续也方便像接口一样统一管理不同用户(向上转型)
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 doOpration(int choice, BookList bookList){this.iOperations[choice].work(bookList);};}
NormalUser.java
普通用户
package user;import ioperations.*;import java.util.Scanner;public class NormalUser extends User{public NormalUser(String name) {super(name);//为操作数组iOperations赋值,为普通用户提供他所应有的权限this.iOperations=new IOperation[]{new ExitOperation(),new FindOperation(),new BorrowOperation(),new ReturnOperation()};}@Overridepublic 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;}
}
AdminUser.java
管理员类
package user;import ioperations.*;import java.util.Scanner;public class AdminUser extends User{public AdminUser(String name) {super(name);//为操作数组iOperations赋值,就是为管理员提供他所应有的权限this.iOperations=new IOperation[]{new ExitOperation(),new FindOperation(),new AddOperation(),new DelOperation(),new ShowOperation()};}@Overridepublic 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;}}
Main.java
包含main方法的类
import book.BookList;
import user.AdminUser;
import user.NormalUser;
import user.User;import java.util.Scanner;public class Main {//系统初始化载入方法public static User login(){System.out.println("请输入您的姓名:");Scanner sc=new Scanner(System.in);String name=sc.nextLine();System.out.println("请选择您的身份:1.普通用户 2.管理员");int choice=sc.nextInt();if(choice==1){return new NormalUser(name);}else{return new AdminUser(name);}}public static void main(String[] args) {BookList bookList=new BookList();User user=login();while (true){//打印菜单int choice=user.menu();//根据用户选择进行操作user.doOpration(choice,bookList);}}}
在实践中加深了抽象类、接口设计的理解
开始还是有些懵,为什么就是非得要弄个接口?看着看着懂了。
- 可以观察到用户有很多操作可以选择,怎么用呢?当然是使用各操作类实例化对象、调用方法。但是有那么多不同的操作类,要统一管理起来好一些,且要配合到后续用户数“数字选择”来对应不同操作,怎么办?我们立即想到用数组,但是不同类呀,怎么搞?用父类引用可以接受不同的子类对象!这也是要定义接口,让不同子类实现自己的特定行为的原因之一。
用父类可以将不同子类“串联起来”,统一管理、便于灵活选择使用。
