一、核心需求(以典型功能为例)
- 用户(管理员和普通用户)能够登录到系统上
- 管理员:
(1)查阅某个书籍信息
(2)增加书籍
(3)删除书籍
(4)查看所有书籍列表
(5)退出程序 - 用户:
(1)查阅某个书籍信息
(2)借书
(3)还书
(4)退出程序
二、结合需求找到**“对象”------(需求中重要的名词或操作**)
- 书籍—Book
- 管理员—Admin-----以及管理员的所有操作
- 普通用户—NormalUser------以及普通用户的所有操作
- 书籍列表—BookList
三、各个类的实现
注意:
(1)通过类中的属性描述一本书的信息时,为了使其他使用者不必理解该类的实现细节,就要将这些属性尽可能封装起来------>private(能用private尽量用private)
(2)不能将构造方法设为private,否则就无法在类的外部new这个实例了
(3)如果想要在类的外部访问类内部的私有属性,可以通过public修饰的方法来间接获取(getter方法)或者操作(setter方法)这些属性
(4)对于书籍的操作较多,可专门创建一个operation包来容纳这些操作
(5)在设计用户操作时,可将每个操作都做成一个类,这些操作具有一些共性信息,可将其单独提取出来(目的:消除重复+让看起来不相关的类能够建立联系),做成一个接口,然后让这些类去实现这个接口,同时该接口也为两个用户类里所进行的操作做出了铺垫(即通过这个接口数组来来描述哪个用户都支持什么操作)
(6)命令行操作中需要有菜单(管理员菜单+普通用户菜单),以便让用户可以通过菜单提示来选择操作
(7)准备好前期工作后(即大体上对每个类有了一定的概述),通过一个Main类进行整合
代码实现:
- Book.java
package java_BookSystem;
//Book类用来描述一本书的信息
//通过类中的属性对信息进行描述
public class Book {
//为了实现封装,能用private就尽量用private
private String name;
private String author;
private double price;
private String type;
//书的状态(是否被借出)---就地初始化
private boolean isBorrowed=false;
//使用构造方法对属性进行初始化
public Book(String name, String author, double price, String type) {
this.name = name;
this.author = author;
this.price = price;
this.type = type;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
", type='" + type + '\'' +
", isBorrowed=" + isBorrowed +
'}';
}
public String getName() {
return name;
}
public boolean isBorrowed() {
return isBorrowed;
}
public void setBorrowed(boolean borrowed) {
isBorrowed = borrowed;
}
}
- BookList.java
package java_BookSystem;
public class BookList {
//BookList类可将多个(可利用数组)Book对象组织起来
//列表中书籍最大容纳量设为100
private Book[] books = new Book[100];
//书籍列表中当前书的个数
private int size = 0;
//不能将构造方法设为private,否则就不能在类的外部new这个实例了
public BookList() {
books[0] = new Book("红楼梦", "曹雪芹", 80, "古典名著");
books[1] = new Book("三国演义", "罗贯中", 80, "古典名著");
books[2] = new Book("活着", "余华", 60, "当代文学");
size=3;
}
//获取书籍信息操作(通过数组下标实现)------getter方法
//由于books数组访问权限为private,可以用public方法,以便在类的外部能够使用到
public Book getBook(int index){
return books[index];
}
//修改书籍信息操作------setter方法
public void setBook(int index,Book book){
books[index]=book;
}
//获取列表中书籍个数操作
public int getSize(){
return size;
}
//修改列表中书籍个数操作
public void setSize(int size){
this.size=size;
}
}
- User.java
package java_BookSystem;
import java_BookSystem.operation.IOperation;
//User这个类是用来作为Admin和NormalUser的父类
//用来存放两个子类的公共信息(name和operation)
//User这个类不需要进行实例化(角色只有两种),只是为了被子类继承,因此可让这个类为抽象类
//当后面的操作对User进行实例化时,编译器就会报错
abstract public class User {
protected String name;
//看起来是个接口数组,但接口不能进行实例化
//所以这个数组中放置的内容实际上是实现了该接口的类的实例
protected IOperation[] operations;
//创建打印用户菜单方法
//因为不同用户所支持的操作不同,因此将menu()做成一个抽象方法
//由该类的子类去重写这个方法
public abstract int menu();
//执行操作的方法
public void doOperation(int choice,BookList bookList){
IOperation operation= this.operations[choice-1];
operation.work(bookList);
}
}
- Admin.java
package java_BookSystem;
import java_BookSystem.operation.*;
import java.util.Scanner;
public class Admin extends User{
public Admin(String name){
this.name=name;
//管理员可进行的操作,将这些实例放到这个数组中
this.operations=new IOperation[]{
new FindOperation(),
new AddOperation(),
new DelOperation(),
new DisplayOperation(),
new ExitOperation(),
};
}
//管理员菜单界面
@Override
public int 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("5.退出程序");
System.out.println("--------------------------");
System.out.println("请输入您的选择:");
Scanner sc=new Scanner(System.in);
int choice=sc.nextInt();
return choice;
}
}
- NormalUser.java
package java_BookSystem;
import java_BookSystem.operation.*;
import java.util.Scanner;
public class NormalUser extends User{
public NormalUser(String name){
this.name=name;
this.operations=new IOperation[]{
new FindOperation(),
new BorrowOperation(),
new ReturnOperation(),
new ExitOperation()
};
}
@Override
public int 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("--------------------------");
System.out.println("请输入您的选择:");
Scanner sc=new Scanner(System.in);
int choice=sc.nextInt();
return choice;
}
}
- IOperation.java
package java_BookSystem.operation;
import java_BookSystem.BookList;
public interface IOperation {
//将所有操作的共性信息(此处为work方法)提取出来
//该方法为一个抽象方法
void work(BookList bookList);
}
- AddOperation.java
package java_BookSystem.operation;
import java_BookSystem.Book;
import java_BookSystem.BookList;
import java.util.Scanner;
//增加书籍
public class AddOperation implements IOperation{
@Override
public void work(BookList bookList){
//以下为具体新增的操作
System.out.println("增加书籍");
Scanner sc=new Scanner(System.in);
System.out.println("请输入新的书籍名称:");
String name=sc.next();
System.out.println("请输入新的书籍作者:");
String author=sc.next();
System.out.println("请输入新的书籍价格:");
double price=sc.nextDouble();
System.out.println("请输入新的书籍类型:");
String type=sc.next();
//创建新增书籍实例
Book newbook=new Book(name,author,price,type);
//将新增书籍放置BookList末尾
//先获取到当前列表size
int curSize=bookList.getSize();
bookList.setBook(curSize,newbook);
//修改列表size
bookList.setSize(curSize+1);
System.out.println("添加成功!");
}
}
- BorrowOperation.java
package java_BookSystem.operation;
import java_BookSystem.BookList;
import java.util.Scanner;
public class BorrowOperation implements IOperation {
@Override
public void work(BookList bookList) {
//借书操作
Scanner scanner = new Scanner(System.in);
System.out.println("借书");
System.out.println("请输入您所借阅书籍的名称:");
String name=scanner.next();
int i = 0;
for (; i < bookList.getSize(); i++) {
if (name.equals(bookList.getBook(i).getName())) {
break;
}
}
if (i >= bookList.getSize()) {
//未找到匹配书籍
System.out.println("您所借阅的书籍在系统中不存在!");
}
//如果找到书籍,判断该数是否被借阅
// 如果被借阅
if(bookList.getBook(i).isBorrowed()){
System.out.println("该书已被借出,借阅失败!");
return;
}
//如果未被借出, 修改对应标记位
bookList.getBook(i).setBorrowed(true);
System.out.println("借阅成功!");
}
}
- DelOperation.java
package java_BookSystem.operation;
import java_BookSystem.BookList;
import java.util.Scanner;
//删除书籍
public class DelOperation implements IOperation {
@Override
public void work(BookList bookList) {
//以下为具体删除操作
System.out.println("删除书籍");
System.out.println("请输入要删书籍的名称:");
Scanner scanner = new Scanner(System.in);
String name = scanner.next();
int i = 0;
for (; i < bookList.getSize(); i++) {
if (name.equals(bookList.getBook(i).getName())) {
break;
}
}
if (i >= bookList.getSize()) {
//未找到匹配书籍,删除失败
System.out.println("您所输入书籍在系统中不存在,删除失败!");
return;
}
//找到匹配书籍,删除i位置元素
//将i位置元素放在数组末尾,size--
if (i == bookList.getSize() - 1) {
//如果想要删除书籍正好在列表末尾,size--即可
bookList.setSize(bookList.getSize() - 1);
return;
}
//如果不是在列表末尾,先将最后一个元素赋值给要删除元素位置上,再size--
bookList.setBook(i, bookList.getBook(bookList.getSize() - 1));
bookList.setSize(bookList.getSize() - 1);
System.out.println("删除成功!");
}
}
- DisplayOperation.java
package java_BookSystem.operation;
import java_BookSystem.BookList;
public class DisplayOperation implements IOperation {
@Override
public void work(BookList bookList) {
//显示书籍列表
System.out.println("显示书籍列表");
//这样写打印出的是
for(int i=0;i<bookList.getSize();i++){
System.out.println(bookList.getBook(i));
}
//此处应再重写Book类的toString方法,否则打印时调用的是的是Object的toString
//打印出的是hash code
// 快捷方式:ctrl+左键跳转到对应的类
}
}
- FindOperation.java
package java_BookSystem.operation;
import java_BookSystem.BookList;
import java.util.Scanner;
//查找书籍信息
public class FindOperation implements IOperation{
@Override
public void work(BookList bookList){
//以下为具体查找操作
Scanner scanner = new Scanner(System.in);
System.out.println("查阅书籍信息");
System.out.println("请输入要查找书籍的名称:");
String name = scanner.next();
int i = 0;
for (; i < bookList.getSize(); i++) {
if (name.equals(bookList.getBook(i).getName())) {
break;
}
}
if (i >= bookList.getSize()) {
//未找到匹配书籍,删除失败
System.out.println("您所查找的书籍在系统中不存在!");
return;
} System.out.println(bookList.getBook(i));
}
}
- ReturnOperation.java
package java_BookSystem.operation;
import java_BookSystem.BookList;
import java.util.Scanner;
public class ReturnOperation implements IOperation {
@Override
public void work(BookList bookList) {
//还书操作
Scanner scanner = new Scanner(System.in);
System.out.println("还书");
System.out.println("请输入所还书籍名称:");
String name = scanner.next();
int i = 0;
for ( ;i < bookList.getSize(); i++) {
if (name.equals(bookList.getBook(i).getName())) {
break;
}
}
if (i >= bookList.getSize()) {
System.out.println("您所输入书籍在系统中不存在,归还失败!");
return;
}
if(!bookList.getBook(i).isBorrowed()){
System.out.println("该书未被借出,归还失败!");
return;
}
bookList.getBook(i).setBorrowed(false);
System.out.println("归还成功!");
}
}
- ExitOperation.java
package java_BookSystem.operation;
import java_BookSystem.BookList;
public class ExitOperation implements IOperation {
@Override
public void work(BookList bookList) {
//退出程序
System.out.println("退出程序");
//通过exit方法直接结束当前程序
//参数0--->进程退出码(表示进程正常执行完毕)
//非0----->异常退出
System.exit(0);
}
}
- Main.java
import java_BookSystem.Admin;
import java_BookSystem.BookList;
import java_BookSystem.NormalUser;
import java_BookSystem.User;
import java.util.Scanner;
public class Main {
public static void main(String[] args){
//1.准备好书籍数据--->创建BookList实例
BookList bookList=new BookList();
//2.登录过程--->创建用户(不用关注用户是那种身份)
User user=login() ;
//3.进入主循环
while(true){
//此处user是父类的引用
//user调用哪个用户的方法,就看user指向的是那个子类的实例
//此处体现的是多态
int choice=user.menu();
//通过用户的选择来实现相应操作
//将用户输入的选择和所要操作的书籍信息传进去
user.doOperation(choice,bookList);
}
}
//登录
public static User login() {
Scanner sc=new Scanner(System.in);
System.out.println("请输入您的姓名:");
String name=sc.next();
System.out.println("请输入您的身份:1.管理员 2.普通用户");
int who=sc.nextInt();
if(who==1){
//向上转型(发生在方法返回时)---多态
return new Admin(name);
}
//向上转型(发生在方法返回时)---多态
return new NormalUser(name);
}
}