图书管理系统
这里我们主要是了解面向对象的思想,功能方面可能不那么如尽人意(如果想要更全面的功能,可自行优化)。
这里实现的图书管理系统分为管理用户端和普通用户端。下面是他们的操作。
管理用户端:
- 查阅书籍
- 增加书籍
- 删除书籍
- 打印书籍列表
- 退出
普通用户端:
- 查询书籍
- 借阅书籍
- 归还书籍
- 退出
图书管理系统要有书,那么我们首先创建一个 Book 类,它存储着一本书的基本信息。
代码如下:
package book;
public class Book {
private String name;
private String author;
private double price;
private String type;
private boolean condition; //我们用 condition来表示书当前的状态,false为 未借出,true为 已借出
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 double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public boolean isCondition() {
return condition;
}
public void setCondition(boolean condition) {
this.condition = condition;
}
// 重写 Object类的 toString方法,
// 这里的条件运算符运用的非常巧妙来打印书的状态
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
", type='" + type + '\'' +
(condition == false ? ", 未借出" : ", 已借出") +
'}';
}
}
由于我们是在面向对象编程,为了更好的管理书籍,我们再创建一个书架来保存所有书的基本信息(可能在C语言这种面向过程的语言中就会直接传入存放所有书籍的信息的首地址,而不会再创建一个变量来保存所有书籍信息)。
BookShelf类
package book;
public class BookShelf {
public Book[] books;
private int allBooksCount;
// 开始说了我们这里只是了解面向对象编程的思想,
// 我们实现的图书管理系统并没有使用文件来保存书的基本信息,
// 为了能更好的检测各种功能,我们先初始化几本书。
public BookShelf() {
this.books = new Book[]{
new Book("三国演义", "罗贯中", 56, "小说"),
new Book("西游记", "吴承恩", 62, "小说"),
new Book("红梦楼", "曹雪芹", 76, "小说"),
new Book("水浒传", "施耐庵", 96, "小说")
};
this.allBooksCount = 4;
}
public int bookSize(){
return books.length;
}
public void setBooks(int pos, Book book) {
this.books[pos] = book;
}
public Book getBook(int pos) {
return this.books[pos];
}
public void setAllBooksCount(int allBooksCount) {
this.allBooksCount = allBooksCount;
}
public int getAllBooksCount() {
return this.allBooksCount;
}
}
接下来就是设计操作方法了,由于我们是在面向对象编程,我们把每一种操作方法都当做是一个对象来处理,我们用一个接口来声明一个方法,再用不同的操作方法来实现这个接口。到时候调用就变得十分简单,因为调用实现接口了的方法的时候,他不管类型,只管该方法有没有实现调用的接口。
代码如下:
IOperation接口
package operation;
import book.BookShelf;
public interface IOperation {
void work(BookShelf bookShelf);
}
AddOperation类
package operation;
import book.Book;
import book.BookShelf;
import java.util.Arrays;
import java.util.Scanner;
public class AddOperation implements IOperation {
@Override
public void work(BookShelf bookShelf) {
System.out.println("新增图书!");
Scanner scanner = new Scanner(System.in);
System.out.print("请输入书的名称:");
String name = scanner.nextLine();
System.out.print("请输入书的作者:");
String author = scanner.nextLine();
System.out.print("请输入书的类型:");
String type = scanner.nextLine();
System.out.print("请输入书的价格:");
double price = scanner.nextDouble();
for (int i = 0; i < bookShelf.getAllBooksCount(); i++) {
Book book = bookShelf.getBook(i);
if (name.equals(book.getName())) {
System.out.println("存在该书,无法添加!");
return;
}
}
Book book = new Book(name, author, price, type);
if (bookShelf.getAllBooksCount() == bookShelf.bookSize()) {
//空间扩容
bookShelf.books = Arrays.copyOf(bookShelf.books, 2 * bookShelf.bookSize());
}
//放入书架
bookShelf.setBooks(bookShelf.getAllBooksCount(), book);
bookShelf.setAllBooksCount(bookShelf.getAllBooksCount() + 1);
System.out.println("新增成功!");
}
}
BorrowOperation类
package operation;
import book.Book;
import book.BookShelf;
import java.util.Scanner;
public class BorrowOperation implements IOperation {
@Override
public void work(BookShelf bookShelf) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入你要借阅的书的名称:");
String name = scanner.nextLine();
for (int i = 0; i < bookShelf.getAllBooksCount(); i++) {
Book book = bookShelf.getBook(i);
if (name.equals(book.getName()) && !book.isCondition()) {
//修改图书状态
book.setCondition(true);
System.out.println("借阅成功!");
return;
}
}
System.out.println("没有此书,无法借阅或者此书已借出!");
}
}
DeleteOperation类
package operation;
import book.Book;
import book.BookShelf;
import java.util.Scanner;
public class DeleteOperation implements IOperation {
@Override
public void work(BookShelf bookShelf) {
System.out.println("删除图书!");
Scanner scanner = new Scanner(System.in);
System.out.print("请输入输出图书的名称:");
String name = scanner.nextLine();
for (int i = 0; i < bookShelf.getAllBooksCount(); i++) {
Book book = bookShelf.getBook(i);
if (name.equals(book.getName())) {
for (int j = i; j < bookShelf.getAllBooksCount() - 1; j++) {
//面向对象编程
Book book1 = bookShelf.getBook(j + 1);
bookShelf.setBooks(j, book1);
//相当于 bookShelf.books[j]=bookShelf.books[j+1];
}
System.out.println("删除成功!");
//防止内存泄漏
bookShelf.setBooks(bookShelf.getAllBooksCount() - 1, null);
bookShelf.setAllBooksCount(bookShelf.getAllBooksCount() - 1);
return;
}
}
System.out.println("不存在此书,无法删除!");
}
}
DisplayOperation类
package operation;
import book.Book;
import book.BookShelf;
public class DisplayOperation implements IOperation {
@Override
public void work(BookShelf bookShelf) {
System.out.println("显示所有图书信息!");
for (int i = 0; i < bookShelf.getAllBooksCount(); i++) {
Book book = bookShelf.getBook(i);
System.out.println(book);
}
}
}
ExitOperation类
package operation;
import book.BookShelf;
public class ExitOperation implements IOperation {
@Override
public void work(BookShelf bookShelf) {
System.out.println("退出图书管理系统!");
System.exit(0);
}
}
FindOperation类
package operation;
import book.Book;
import book.BookShelf;
import java.util.Scanner;
public class FindOperation implements IOperation {
@Override
public void work(BookShelf bookShelf) {
Scanner scanner = new Scanner(System.in);
System.out.println("查找图书!");
System.out.print("请输入你要查找的书名:");
String name = scanner.nextLine();
for (int i = 0; i < bookShelf.getAllBooksCount(); i++) {
Book book = bookShelf.getBook(i);
if (name.equals(book.getName())) {
System.out.println("找到此书,信息如下:");
System.out.println(book);
return;
}
}
System.out.println("没有此书!");
}
}
ReturnOperation类
package operation;
import book.Book;
import book.BookShelf;
import java.util.Scanner;
public class ReturnOperation implements IOperation {
@Override
public void work(BookShelf bookShelf) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入你要归还的书的名称:");
String name = scanner.nextLine();
for (int i = 0; i < bookShelf.getAllBooksCount(); i++) {
Book book = bookShelf.getBook(i);
if (name.equals(book.getName()) && book.isCondition()) {
//设置图书状态
book.setCondition(false);
System.out.println("归还成功!");
return;
}
}
System.out.println("没有此书,无法归还或该书没有借出!");
}
}
然后就是设计用户了,我们这里有两种用户,管理用户(AdminUser),和普通用户(NormalUser),他们都是用户,都有一些相同的属性,我们让这两种用户都继承一个用户(User),同时也方面了方法的调用。
代码如下:
User类
package user;
import book.BookShelf;
import operation.IOperation;
public abstract class User {
public String name;
// 我们这里定义了一个接口类型的数组,
// 然后我们在不同的用户端存放着各种已经实现了接口的操作方法,
// 到时候调用的时候就不必担心如何调用了
protected IOperation[] iOperations;
public User(String name) {
this.name = name;
}
public abstract void menu();
//调用当前对象的操作方法的方法
public void doOperation(int choice, BookShelf bookShelf) {
this.iOperations[choice].work(bookShelf);
}
}
AdminUser类
package user;
import operation.*;
public class AdminUser extends User {
public AdminUser(String name) {
super(name);
//管理用户端的存放着各自操作方法的对象,注意到对应菜单
this.iOperations = new IOperation[]{
new ExitOperation(),
new FindOperation(),
new AddOperation(),
new DeleteOperation(),
new DisplayOperation()
};
}
public void menu() {
System.out.println("-------------------------");
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("-------------------------");
}
}
NormalUser类
package user;
import operation.*;
public class NormalUser extends User {
public NormalUser(String name) {
super(name);
//普通用户端的存放着各自操作方法的对象,注意到对应菜单
this.iOperations = new IOperation[]{
new ExitOperation(),
new FindOperation(),
new BorrowOperation(),
new ReturnOperation()
};
}
public void menu() {
System.out.println("-------------------------");
System.out.println("------- 普通用户菜单 -------");
System.out.println("--------1.查找图书--------");
System.out.println("--------2.借阅图书--------");
System.out.println("--------3.归还图书--------");
System.out.println("--------0.退出系统--------");
}
}
最后就只剩下主函数了,我们在主函数中要确认用户的身份,由于前面说了只是了解面向对象的思想,我们这里只是用了一个很简单的登录方式。
import book.BookShelf;
import user.AdminUser;
import user.NormalUser;
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();
while (true) {
System.out.print("请输入你的身份:(1为管理员,0为普通用户)");
int choice = scanner.nextInt();
switch (choice) {
case 1:
return new AdminUser(name);
case 0:
return new NormalUser(name);
default:
System.out.println("选择错误,请重新选择!");
break;
}
}
}
public static void main(String[] args) {
BookShelf bookShelf = new BookShelf();
// 我们不确认返回的是哪一种用户,
// 我们用父类 User接受返回的用户类型
User user = login();
Scanner scanner = new Scanner(System.in);
System.out.println("您好," + user.name + ",欢迎来到图书管理系统!");
while (true) {
user.menu();
int choice = scanner.nextInt();
//利用动态绑定,对应用户端直接调用的对应的操作方法
user.doOperation(choice, bookShelf);
}
}
}
从主函数就可以看出面向对象的特性,主函数异常简洁,绝大部分工作都交给对象去处理了。在面向对象编程中,我们的思维也变得异常清晰,这也正是我们人的思维方式。