
- 程序介绍
- 实现思路和内容概括
- 代码实现
- 顺序表——bookList(书架)和book(书)
- book类:
- bookList类
- *** 作——各种的 *** 作类
- IOperation接口
- AddOperation类
- BorrowOperation类
- DelOperation类
- DisplayOperation类
- ExitOperation类
- FindOperation类
- ReturnOperation类
- 使用者——AdminUser(管理员)和NormalUser(普通用户)
- User抽象类
- AdminUser类
- NormalUser类
- Main类
- 运行展示
- 总结
通过前面的学习,我们理解了面向对象的三个基本特性:封装,多态,继承。也简单了学习了数据结构中的顺序表和链表的相关知识,这次我们通过将前面所学习的知识相结合,写一个图书管理系统,只要有分为两种模式:普通人和管理员模式。普通人可以查找图书,借阅图书,归还图书;管理员可以查找图书,新增图书,删除图书,显示图书。下面我们实现过程。
实现思路和内容概括面向对象编程要求我们将对象能够罗列出来,首先通过对程序介绍的分析,我们可以举出这么几个对象:书籍,书架,普通人,管理员,各种 *** 作。书架是用来存储书籍的,也就是数据结构中的存储的形式,这里我们可以用顺序表存储。
代码实现 顺序表——bookList(书架)和book(书) 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{" +
"name='" + name + ''' +
", author='" + author + ''' +
", price=" + price +
", type='" + type + ''' +
((isBorrowed == true) ? " 已经被借出 " : " 未被借出 ") +
'}';
}
}
首先我们定义一个book类,这个类中有5个属性:书名,作者,价格,类型和是否被借出,分别是String类型,String类型,int类型,String类型和Boolean类型,构造方法就是将这五种属性值赋值给实例化的对象。下面的方法是get和set五种属性,并且重写了toString方法。
bookList类public class BookList {
private Book[] books = new Book[10];
private int usedSize;
public BookList() {
books[0] = new Book("三国演义", "罗贯中", 17, "小说");
books[1] = new Book("西游记", "吴承恩", 47, "小说");
books[2] = new Book("水浒传", "施耐庵", 37, "小说");
this.usedSize = 3;
}
public int getUsedSize() {
return usedSize;
}
public void setUsedSize(int usedSize) {
this.usedSize = usedSize;
}
public Book getPos(int pos) {
return this.books[pos];
}
public void setBook(int pos, Book book) {
this.books[pos] = book;
}
}
bookList类我们可以把它看做成书架,也就是顺序表,因此我们需要创建一个Book类型的数组(10个元素)和usedSize用于计数,每有一本书放入书架(即数组元素被占用一个)那么usedSize加上1,构造方法我们是实例化三个Book类型的对象,分别放入顺序表中,在将usedSize置为3(因为顺序表中有了3本书),getUsedSize()和setUsedSize()方法分别是获取usedSize的值和设置usedSize的值,getPos()方法是获取pos的位置的一本书(也就是从书架上拿书的 *** 作),setBook()方法是在pos的位置放置一本书(也就是在书架上放置一本书)。
*** 作——各种的 *** 作类 IOperation接口import book.BookList;
import java.util.Scanner;
public interface IOperation {
Scanner scanner = new Scanner(System.in);
void work(BookList bookList);
}
这是一个接口,由这个接口被继承使得继承这个接口的类有各式各样的 *** 作,删除一本书,打印所有书等等的 *** 作,首先Scanner scanner = new Scanner(System.in);是为了实例化scanner这个对象,这个对象用来实现输入的 *** 作(一些功能需要我们输入相关信息), void work(BookList bookList);就是用来实现 *** 作功能的方法,继承该接口的类都要重写这个方法。
AddOperation类public class AddOperation implements IOperation{
public void work(BookList bookList) {
System.out.println("新增图书!");
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 size = bookList.getUsedSize();
bookList.setBook(size,book);
bookList.setUsedSize(size+1);
System.out.println("新增图书成功!");
}
}
这是实现新增书籍的功能,首先打印“新增图书!”和“请输入图书的名字:”,此时输入图书的名字存进name中去,同理,接着是输入图书的作者,类型,价格,需要注意的是价格用int来接收,然后实例化一本书book对象,通过构造方法将参数传给book,在用size接收bookList中的size,此时通过bookList对象的setBook方法将刚刚创建的book对象存放进bookList中去。最后让usedSize+1,并打印“新增图书成功!”,完成增加书籍的 *** 作。
BorrowOperation类public class BorrowOperation implements IOperation {
public void work(BookList bookList) {
System.out.println("借阅图书!");
System.out.println("请输入你要借阅的图书的名字:");
String name = scanner.nextLine();
int size = bookList.getUsedSize();
for (int i = 0; i < size; i++) {
Book book = bookList.getPos(i);
if (book.getName().equals(name)){
book.setBorrowed(true);
System.out.println("借阅成功!");
System.out.println(book);
return;
}
}
System.out.println("没有你要借阅的这本书!");
}
}
这是实现借阅书籍的功能,首先打印“借阅书籍!”和“请输入你要借阅的图书的名字:”,然后输入名字,并用name存储起来,并且用size接收bookList中的usedSize,通过循环寻找与bookList中book名字相对应的书名,如果相同,那么将书的isBorrowed属性改为true,并打印“借阅成功!”和整个书的相关信息,否则打印“没有你要借阅的这本书!”
DelOperation类public class DelOperation implements IOperation {
public void work(BookList bookList) {
System.out.println("删除图书!");
System.out.println("请输入你要删除的图书的名字:");
String name = scanner.nextLine();
int currentSize = bookList.getUsedSize();
int index = 0;//存储找到的下标
int i = 0;
for (i = 0; i < currentSize; i++) {
Book book = bookList.getPos(i);
if (book.getName().equals(name)) {
index = i;
break;
}
}
if (i >= currentSize) {
System.out.println("没有你要删除的这本书!");
return;
}
for (int j = index; j < currentSize - 1; j++) {
Book book = bookList.getPos(j + 1);
bookList.setBook(j, book);
}
bookList.setBook(currentSize, null);
bookList.setUsedSize(currentSize - 1);
System.out.println("删除成功!");
}
}
这个实现删除图书的功能,删除 *** 作相对比较复杂,复杂的地方就在于如何删除这本书,并且将后面的图书往前移(顺序表的弊端),首先还是一样,打印“删除图书!”和“请输入你想要删除的图书名字:”,然后通过输入用name接收名字,同样用currentSize接收bookList中的usedSize,然后通过循环找与name相对应的书籍,如果i>=currentSize,即遍历完整个bookList(书架)都没有找到,打印“没有你要删除的图书”并结束删除 *** 作(return;),否则,表示有要删除的图书,用index接收删除图书的位置,再次通过循环,从index开始,依次得到后面的一本图书,覆盖掉前面一本图书(比如:从index开始,通过getPos()方法得到index+1位置的图书,然后用setBook()方法覆盖掉index位置的图书),最后用null覆盖掉最后一本图书(也就是currentSize位置的图书),并让usedSize-1,打印删除成功。
DisplayOperation类public class DisplayOperation implements IOperation{
public void work(BookList bookList) {
System.out.println("打印图书!");
int size = bookList.getUsedSize();
for (int i = 0; i < size; i++) {
Book book = bookList.getPos(i);
System.out.println(book);
}
}
}
这个实现打印全部图书的功能,相对比较简单,首先得到bookList中的usedSize,然后输出“打印图书!”,通过循环得到每个对应位置的book,再将图书打印出来。
ExitOperation类public class ExitOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("退出系统!");
System.exit(0);
}
}
这个实现的是退出系统的功能,非常简单,不在赘述。
FindOperation类public class FindOperation implements IOperation {
@Override
public void work(BookList bookList) {
System.out.println("查找图书!");
String name = scanner.nextLine();
int size = bookList.getUsedSize();
for (int i = 0; i < size; i++) {
Book book = bookList.getPos(i);
if (name.equals(book.getName())){
System.out.println("找到了这本书!,信息如下:");
System.out.println(book);
return;
}
}
System.out.println("没有找到!");
}
}
这个实现的是查找图书的功能,相对也比较简单,首先用name接收输入的名字,然后用size接收usedSize,通过循环寻找与bookList中图书book相对应的书籍,如果相同,则打印“找到了这本书!信息如下:”,并输出这本书,否则打印“没有找到!”。
ReturnOperation类public class ReturnOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("归还图书!");
System.out.println("请输入你要归还的图书的名字:");
String name = scanner.nextLine();
int size = bookList.getUsedSize();
for (int i = 0; i < size; i++) {
Book book = bookList.getPos(i);
if (book.getName().equals(name)){
book.setBorrowed(false);
System.out.println("归还成功!");
System.out.println(book);
return;
}
}
System.out.println("没有你要归还的这本书!");
}
}
这个实现归还图书的功能,跟借阅书籍非常相近,这里不在赘述。
使用者——AdminUser(管理员)和NormalUser(普通用户)使用人员有两种——一种是管理员(查找图书,新增图书,删除图书,显示图书,退出系统);另一种是普通用户(查找图书,借阅图书,归还图书,退出系统),因此我们需要用一个User抽象类,让AdminUser(管理员)类和NormalUser(普通用户)类来继承。
User抽象类public abstract class User {
protected String name;
protected IOperation[] iOperations;
public User(String name) {
this.name = name;
}
public abstract int menu();
public void doWork(int choice, BookList bookList) {
iOperations[choice].work(bookList);
}
}
首先有两个成员变量,分别为name(类型:String)和iOperations(类型:IOperation[])。构造方法是赋值姓名,有一个抽象方法打印菜单,继承User的类需要重写,还有一个方法就是实现具体的某项 *** 作。
AdminUser类public class AdminUser extends User{
public AdminUser(String name) {
super(name);
this.iOperations = new IOperation[]{
new ExitOperation(),
new FindOperation(),
new AddOperation(),
new DelOperation(),
new DisplayOperation()
};
}
@Override
public int menu() {
System.out.println("==================管理员菜单==================");
System.out.println("hello," + this.name + "欢迎来到图书管理系统!");
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);
int choice = scanner.nextInt();
return choice;
}
}
这个是管理员类,首先是一个参数name的构造方法,并且将管理员的 *** 作放入IOperation数组中去,之后是重写打印菜单的方法,用choic接收输入的整型,并返回choice。
NormalUser类public class NormalUser extends User{
public NormalUser(String name) {
super(name);
this.iOperations = new IOperation[]{
new ExitOperation(),
new FindOperation(),
new BorrowOperation(),
new ReturnOperation()
};
}
@Override
public int menu() {
System.out.println("==================普通用户的菜单==================");
System.out.println("hello," + this.name + "欢迎来到图书管理系统!");
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);
int choice = scanner.nextInt();
return choice;
}
}
这个是普通用户类,与管理员类相类似。不在过多赘述。
Main类public class Main {
public static User login() {
System.out.println("请输入你的姓名:");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
System.out.println("请输入你的身份:1 --> 管理员。0 --> 普通用户");
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);
}
}
}
这个类是执行类,首先执行main方法,实例化一个bookList(此时里面有三本书),然后调用login()方法,输入姓名,并用name存储起来,然后通过选择身份,确定是管理员(1)还是普通用户(0),如果是管理员,就实例化管理员类(AdminUser(name)),如果是普通用户,就实例化普通用户类(NormalUser(name)),并用user接收返回的对象。然后进入循环,用choice接收user调用的menu()方法,最后执行user的doWork()方法。
运行展示
这次的图书管理系统将前面的学习过程中绝大部分知识点都结合到了一起,因此很有必要多练习,多理解,自己不妨试一试自己写一写,这也有助于编程水平的提高,当然这样的图书管理系统是有很多改进的地方的,比如:顺序表的弊端,我们可以把顺序表改成链表,又比如其他的一些功能。好了此次的博客就到这里,如果对你有所帮助,别忘了点赞。如果有问题或者建议,欢迎私信和评论。谢谢各位!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)