目录
本章作为一个练习,对于前面学过的那些语法进行一个整合运用。
语法方面主要包括:封装、继承、多态、抽象类和接口。
首先,我们将整个系统分为4个包,

分别是Book类用于封装书和书架的具体信息。
Main包也就是封装主类,用于对整个系统的具体操作。
Operate包用于封装具体的操作。
User包用于管理用户信息。
我们一个包一个包来讲解。

Book包分为两类,分别是书和书架。
该类主要是对书的一些基本信息进行封装,并且提供Getting和Setting方法。
- package Book;
-
- public class Book {
- private String name;//书名
- private String author;//作者
- private int price;//价格
- private String type;//类型
- private boolean isBorrowed;//是否被借出
-
- 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 isBorrowed() {
- return isBorrowed;
- }
-
- public void setBorrowed(boolean borrowed) {
- isBorrowed = borrowed;
- }
-
- @Override
- public String toString() {
- return "Book.Book{" +
- "name='" + name + '\'' +
- ", author='" + author + '\'' +
- ", price=" + price +
- ", type='" + type + '\'' +
- ", isBorrowed=" + isBorrowed +
- //", isBorrowed=" + isBorrowed +
- (isBorrowed ? " 已经被借出" : " 未被借出") +
- '}';
- }
- }
书架的创建:
包括了初始化,以及对一些书籍的基本操作。
- package Book;
-
- public class BookList {
- private Book[] books = new Book[10];//创建书架
- private int usedSize;//记录书架上书的数量
- public BookList() {//初始化3本书
- books[0] = new Book("我们仨","杨绛",89,"文学");
- books[1] = new Book("明朝那些事","当年明月",78,"历史");
- books[2] = new Book("红楼梦","曹雪芹",49,"小说");
- this.usedSize = 3;
- }
-
- public Book[] getBooks() {
- return books;
- }
-
- public void setBooks(int pos,Book book) {
- books[pos] = book;
- }
-
- public int getUsedSize() {
- return usedSize;
- }
-
- public void setUsedSize(int usedSize) {
- this.usedSize = usedSize;
- }
-
- public Book getBook(int pos) {
- return this.books[pos];
- }
-
- //重写setBook方法作用于设置图书(增删)
- public void setBook(Book book) {
- this.books[usedSize] = book;
- }
- public void setBook(int pos,Book book) {
- this.books[pos] = book;
- }
- }

User包被分为三类,其中User类是抽象类,用于管理人员类和普通用户类继承。
AdminUser是管理类,NormalUser类是普通用户类。
因为对于不同的用户而言,他们的访问权限是不同的,所以需要将菜单抽象出来以示区分。
另外就是基本信息。
- package User;
-
- import Book.BookList;
- import Operate.MyOperate;
-
- //抽象出menu()菜单方法
- public abstract class User {
- //protected是访问权限,改为更大的也可以
- protected String name;
- protected MyOperate[] myOperate;//等会到Operate包再讲
- //用户信息
- public User(String name) {
- this.name = name;
- }
- public abstract int menu();
- //作用于main方法中对不同的用户进行区分
- public void doWork(int choice, BookList bookList) {
- this.myOperate[choice].work(bookList);
- }
- }
这里开辟的MyOperate数组是对管理人员的访问权限开辟空间,其中功能包括 退出,查找,增加,删除,显示。

- package User;
-
- import Operate.*;
-
- import java.util.Scanner;
-
- public class AdminUser extends User {
- //管理人员所拥有的访问权限
- public AdminUser(String name) {
- super(name);
- this.myOperate = new MyOperate[]{
- new ExitOperation(),
- new FindOperation(),
- new AddOperation(),
- new DelOperation(),
- new ShowOperation(),
- };
- }
- //管理人员拥有的权限
- public int menu() {
- System.out.println("*****************************************");
- System.out.println("hello"+ name +"欢迎来到图书小小练习");
- System.out.println("1:查找图书");
- System.out.println("2:新增图书");
- System.out.println("3:删除图书");
- System.out.println("4:显示图书");
- System.out.println("0:退出系统");
- Scanner scanner = new Scanner(System.in);
- int choice = scanner.nextInt();
- return choice;
- }
- }
这里开辟的MyOperate数组是对普通用户的访问权限开辟空间,其中功能包括 退出,查找,借书,还书。

- package User;
-
- import Operate.*;
-
- import java.util.Scanner;
-
- public class NormalUser extends User {
- //普通用户所拥有的访问权限
- public NormalUser(String name) {
- super(name);
- this.myOperate = new MyOperate[]{
- new ExitOperation(),
- new FindOperation(),
- new BorrowedOperate(),
- new ReturnOperation(),
- };
- }
- //普通用户拥有的权限
- @Override
- public int menu() {
- System.out.println("****************************");
- System.out.println("hello "+name+" 欢迎来到图书小练习");
- System.out.println("1.查找图书!");
- System.out.println("2.借阅图书!");
- System.out.println("3.归还图书!");
- System.out.println("0.退出系统!");
- System.out.println("****************************");
- System.out.println("请输入你的操作:");
- Scanner scanner = new Scanner(System.in);
- int choice = scanner.nextInt();
- return choice;
- }
- }
Operate的各个操作,增、删、查、借书、还书、退出。

我们 Operate包 将普通用户和管理员用户的具体实现操作类全写在Operate包 中。
MyOperate接口只设计好了各个Operation规范(方法)
- package Operate;
-
- import Book.BookList;
-
- public interface MyOperate {
- public void work(BookList bookList);
- }
本类用于添加书籍得基本信息,并且做了基本的判断。
- package Operate;
-
- import Book.Book;
- import Book.BookList;
-
- import java.util.Scanner;
-
- public class AddOperation implements MyOperate {
-
- @Override
- public void work(BookList bookList) {
- 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("输入价格");
- int price = scanner.nextInt();
-
- Book book = new Book(name, author, price, type);
- //得到此时书架上书的数量
- int currentSize = bookList.getUsedSize();
- //遍历,查找是否想添加的书已经存在了
- //默认添加在最后面
- for (int i = 0; i < currentSize; i++) {
- Book tmp = bookList.getBook(i);
- if(tmp.getName().equals(name)) {
- System.out.println("已经存在这本书了,不能再放入了!");
- return;//如果存在即退出
- }
- }
- //如果不存在即添加
- bookList.setBook(book);
- //每添加一本书下表向后移
- bookList.setUsedSize(currentSize + 1);
-
- }
- }
先上代码:
- package Operate;
-
- import Book.Book;
- import Book.BookList;
-
- import java.util.Scanner;
-
- public class DelOperation implements MyOperate {
- @Override
- public void work(BookList bookList) {
- System.out.println("删除图书!");
- System.out.println("请输入你要删除图书的名字:");
- Scanner scanner = new Scanner(System.in);
- String name = scanner.nextLine();
- //得到当前下标
- int currentSize = bookList.getUsedSize();
- int index = -1;
- //遍历,tmp.getName().equals(name)为真即表示书架存在该书
- //否则则该书不存在
- for (int i = 0; i < currentSize; i++) {
- Book tmp = bookList.getBook(i);
- if (tmp.getName().equals(name)) {
- index = i;
- break;
- }
- }
- //图示说明
- for (int j = index; j < currentSize - 1; j++) {
- Book book = bookList.getBook(j+1);
- bookList.setBook(j,book);
- }
-
- bookList.setUsedSize(currentSize - 1);
- //删除对象,把最后一个设置为bull
- bookList.setBook(currentSize - 1, null);
- }
- }
图示:

假设currentSize 在这里,我们想要删掉该书,那么我们就将currentSize + 1 赋值给currentSize;


接着currentSize向后走:
重复上述操作:

知道最后一个:

直接将最后一个删除,毕竟每删除一个都需要将 书架上的书减少一本:

这样也解释了为什么之前需要重写setBook()方法。
该类就只提供一个方法:exit()
- import Book.BookList;
-
- public class ExitOperation implements MyOperate {
- @Override
- public void work(BookList bookList) {
- System.out.println("退出系统!");
- System.exit(0);
- }
- }
为什么exit()方法中的参数是0,因为我们正常退出是就是0:

FindOperation类实现很简单,只需要提供书名再进行遍历,当然也可以根据价格、作者进行遍历。
- package Operate;
-
- import Book.Book;
- import Book.BookList;
-
- import java.util.Scanner;
-
- public class FindOperation implements MyOperate{
- @Override
- public void work(BookList bookList) {
- System.out.println("查找图书!");
- System.out.println("请输入书名!");
- Scanner scanner = new Scanner(System.in);
- String name = scanner.nextLine();
- //获取当前图书在书架得下标
- int currentSize = bookList.getUsedSize();
- //遍历
- for (int i = 0; i < currentSize; i++) {
- //System.out.println(bookList[i]);
- Book book = bookList.getBook(i);
- if (book.getName().equals(name)) {
- System.out.println("找到了这本书");
- System.out.println(book.toString());
- return;
- }
- }
- System.out.println("没有找到"+name);
- }
- }
遍历获取通过Getting方法打印即可。
- package Operate;
-
- import Book.Book;
- import Book.BookList;
-
- public class ShowOperation implements MyOperate {
- @Override
- public void work(BookList bookList) {
- System.out.println("打印所有图书!");
- int currentSize = bookList.getUsedSize();
- for (int i = 0; i < currentSize; i++) {
- Book book = bookList.getBook(i);
- System.out.println(book);
- }
- }
- }
以上便是管理员访问得全部权限,当然有需要还可以自己添加所需要的方法。
后面得便是普通用户特有的权限,普通用户也有FindOperation、ShowOperation。
方法的逻辑很简单,只需稍加注意
- package Operate;
-
- import Book.Book;
- import Book.BookList;
-
- import java.util.Scanner;
-
- public class BorrowedOperate implements MyOperate {
- @Override
- public void work(BookList bookList) {
- System.out.println("借阅图书!");
- System.out.println("请输入你要借阅的图书:");
- Scanner scanner = new Scanner(System.in);
- String name = scanner.nextLine();
- //获取
- int currentSize = bookList.getUsedSize();
- //遍历
- for (int i = 0; i < currentSize; i++) {
- Book book = bookList.getBook(i);
- //不仅需要判断书是否存在书架上,并且还需要判断是否已经借出
- if (book.getName().equals(name) &&
- book.isBorrowed() == false) {
- book.setBorrowed(true);
- System.out.println("借阅成功");
- return;
- }
- }
- }
- }
逻辑于BorrowedOperation类相似
- package Operate;
-
- import Book.Book;
- import Book.BookList;
-
- import java.util.Scanner;
-
- public class ReturnOperation implements MyOperate {
-
- @Override
- public void work(BookList bookList) {
- System.out.println("归还图书!");
- System.out.println("请输入你要归还的图书:");
- Scanner scanner = new Scanner(System.in);
- String name = scanner.nextLine();
- int currentSize = bookList.getUsedSize();
- for (int i = 0; i < currentSize; i++) {
- Book book = bookList.getBook(i);
- if (book.getName().equals(name) &&
- book.isBorrowed()) {
- book.setBorrowed(false);
- System.out.println("归还成功");
- return;
- }
- }
- }
- }
Main类中只有一个类,主类,整个程序的入口。

上代码:
- package Main;
-
- import Book.BookList;
- import User.AdminUser;
- import User.User;
- import User.NormalUser;
- import java.util.Scanner;
-
- public class Main {
- //提供一个静态方法用于创建身份,是判断管理员还是普通用户
- public static User login() {
- System.out.println("请输入你的姓名");
- Scanner scanner = new Scanner(System.in);
- 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) {
- BookList bookList = new BookList();
- User user = login();
- while (true) {
- int choice = user.menu();
- user.doWork(choice,bookList);
- }
- }
- }
这里发生了一个向上转型:

主方法的内容非常简单:
1. 创建一个书架;
2.通过登录方法确认用户信息;
3.一个死循环,不停的使用“权限”,知道用户输入0退出。
这里就体现了面向对象的思想,所有的过程全部封装完成,只对外提供了公开的方法。
本章的思路都非常简单,只是有些地方需要稍加注意,本章的目的便是体验面向对象的思想。
案例演示:
