文章目录
要求介绍
利用前面所学知识:使用类和对象、继承、封装、多态、抽象类、接口、顺序表进行一个简单的代码练习,以熟练掌握这些知识点的应用。
核心需求
1、简单的登录
2、管理端
- 查阅书籍
- 增加书籍
- 删除书籍
- 打印书籍列表
- 退出
3、用户端
- 查询书籍
- 借阅书籍
- 归还书籍
- 退出
项目分析
首先,需要先找实体:书、用户
- 书这个实体所包含的属性:name、author、price、type、 brrowed
- 用户这个实体所包含的属性:name
找到实体之后需要做的事情
这个项目大概就是有书,对书的一些行为操作,还有用户这三种相关的方向。
- 第一步:先建三个包,分别是书(book)、操作(operation)、用户(user),最外层给一个程序的主函数(TestMain)
- 第二步:实现提供的接口,完成每一个操作
- 第三步:把该写的类写完之后进行整合
类的设计
1、创建图书相关的类
第一步:设计数据库
先创建 package book
代码示例:
package com.xiaoba.book;
/**
* Description:设计一个book类,表示一本书,并完成搭建
*/
/*1、设计一个book类,并完成搭建
* 2、alt+insert:提供getter和setter方法
* 3、alt+insert:提供toString 方法*/
public class Book {
private String name;
private String auther;
private int price;
private String type;
private boolean isBorrowed;//默认未借出
//alt+insert-->Constructor提供构造方法
public Book(String name, String auther, int price, String type) {
this.name = name;
this.auther = auther;
this.price = price;
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuther() {
return auther;
}
public void setAuther(String auther) {
this.auther = auther;
}
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 + '\'' +
", auther='" + auther + '\'' +
", price=" + price +
", type='" + type + '\'' +
", isBorrowed=" + isBorrowed +
'}';
}
}
第二步:设计书的列表,Booklist类,booklist实际上是一个顺序表,里面可以放很多的书,顺序表的设计就是里面有一个整型数组,所以booklist的设计就是里面有一个book类型的数组,能放很多的书。
package com.xiaoba.book;
/**
* Description:书籍列表:创建 BookList 类, 用来保存 N 本书
*/
//书的列表,相当于是一个顺序表
public class BookList {
private Book[] books=new Book[100];
private int usedSize=0;
//调用所提供的构造方法
public BookList(){
books[0]=new Book("西游记","罗贯中",99,"名著小说");//给books的0号下标放一本书
books[1]=new Book("水浒传","施耐庵",99,"名著小说");
books[2]=new Book("红楼梦","曹雪芹", 99,"名著小说");
books[3]=new Book("三国演义","吴承恩",99,"名著小说");
this.usedSize=4;
}
//我们可以把所有的操作都写到BookList这个类当中,因为每一个操作都是操作books,但是我不想往里面写,因为我想用接口,
// 写成接口更方便一些,所以不把这些操作写到这个类当中,而是写到单独的一个包里面(operation)
public void setBooks(int pos,Book book){
this.books[pos]=book;
}
public Book getBook(int pos){//得到一本书,给一个pos位置
return this.books[pos];//返回当前books的pos位置的这本书
}
public int getUsedSize() {
return usedSize;
}
public void setUsedSize(int usedSize) {
this.usedSize = usedSize;
}
}
2、创建操作相关的类
先创建一个 package operation
抽象出 Operation 的好处: 让操作和操作之间低耦合, 让操作和用户之间低耦合
实现提供的接口,完成每一个操作
AddOperation的实现
package com.xiaoba.operation;
import com.xiaoba.book.Book;
import com.xiaoba.book.BookList;
import java.util.Scanner;
/**
* Description:添加操作,新增图书
*/
/*因为每一个操作都需要 public void work(BookList bookList){
}
所以干脆提供一个接口,让每一个操作都实现这个接口,然后重写work方法*/
public class AddOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("新增图书");
//默认以尾插法的形式放进去
//1、先拿到所有图书的类型
Scanner scanner=new Scanner(System.in);
System.out.println("请输入图书的名字:");
String name=scanner.nextLine();
System.out.println("请输入图书的作者:");
String author=scanner.nextLine();
System.out.println("请输入图书的价格:");
int price=scanner.nextInt();
System.out.println("请输入图书的类型");
String type=scanner.next();
//注意:nextInt()和nextLine()不能放在一起使用
//2、将拿到的图书类型放到对应的bookList当中
Book book=new Book(name,author,price,type);
int curSize=bookList.getUsedSize();
bookList.setBooks(curSize,book);
bookList.setUsedSize(curSize+1);
System.out.println("新增成功!");
}
public static void main(String[] args) {
}
}
BorrowOperation的实现
package com.xiaoba.operation;
import com.xiaoba.book.Book;
import com.xiaoba.book.BookList;
import java.util.Scanner;
/**
* Description:借阅操作
*/
public class BorrowOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("借阅图书");
Scanner scanner=new Scanner(System.in);
System.out.println("请输入要借阅图书的名字:");
String name=scanner.nextLine();
//借书之前需要先遍历一下查看要借的书是否存在
for(int i=0;i< bookList.getUsedSize();i++){
Book book=bookList.getBook(i);//i号下标
if(book.getName().equals(name)){//拿到书之后,判断当前book的name和你输进来的这个书的name是否一致
//如果为真,说明有这本书,可以借阅
book.setBorrowed(true);//这本书已经被借出去了
System.out.println("借阅成功!");
return;
}
}
System.out.println("没有你要借阅的那本书");
}
}
DelOperation的实现
package com.xiaoba.operation;
import com.xiaoba.book.Book;
import com.xiaoba.book.BookList;
import java.util.Scanner;
/**
* Description:删除操作
*/
public class DelOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("删除图书");
Scanner scanner=new Scanner(System.in);
System.out.println("请输入你要删除的图书的名字:");
String name=scanner.nextLine();
//删除书之前需要先遍历一下查看要删的书是否存在
int i=0;
for(;i< bookList.getUsedSize();i++){
Book book=bookList.getBook(i);//i号下标
if(book.getName().equals(name)){//拿到书之后,判断当前book的name和你输进来的这个书的name是否一致
//如果为真,说明有这本书,可以删除
break;
}
}
if (i==bookList.getUsedSize()){
System.out.println("没有这本书!");
return;
}
//开始删除,删除的方式和顺序表类似
for(int pos=i;pos<bookList.getUsedSize()-1;pos++){
//[pos]=[pos+1];
Book book= bookList.getBook(pos+1);//先拿到bookList,pos+1位置的这一本书
bookList.setBooks(pos,book);//然后把pos位置设置为book这本书
}
//删完之后需要将size大小设置一下
bookList.setUsedSize(bookList.getUsedSize()-1);//在原来的基础上减一
System.out.println("删除成功!");
}
}
DisplayOperation的实现
package com.xiaoba.operation;
import com.xiaoba.book.Book;
import com.xiaoba.book.BookList;
/**
* Description:显示操作
*/
public class DisplayOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("显示图书");
for(int i=0;i<bookList.getUsedSize();i++){
Book book=bookList.getBook(i);
System.out.println(book);
}
}
}
ExitOperation的实现
package com.xiaoba.operation;
import com.xiaoba.book.BookList;
/**
* Description:退出操作
*/
public class ExitOperation implements IOperation {
@Override
public void work(BookList bookList) {
System.out.println("退出系统");
System.exit(1);//退出系统的代码
}
}
FindOperation的实现
package com.xiaoba.operation;
import com.xiaoba.book.Book;
import com.xiaoba.book.BookList;
import java.util.Scanner;
/**
* Description:查找操作
*/
public class FindOperation implements IOperation {
@Override
public void work(BookList bookList) {
System.out.println("查找图书");
Scanner scanner=new Scanner(System.in);
System.out.println("请输入要借阅图书的名字:");
String name=scanner.nextLine();
//借书之前需要先遍历一下查看要借的书是否存在
for(int i=0;i< bookList.getUsedSize();i++){
Book book=bookList.getBook(i);//i号下标
if(book.getName().equals(name)){//拿到书之后,判断当前book的name和你输进来的这个书的name是否一致
//如果为真,说明有这本书,可以查找
System.out.println(book);
System.out.println("查找成功!");
return;
}
}
System.out.println("没有你要查找的那本书");
}
}
IOperation的实现
package com.xiaoba.operation;
import com.xiaoba.book.BookList;
/**
* Description:IOperation
*/
/*因为每一个操作都需要针对bookList这个对象,所以每一个操作都要写这句代码 public void work(BookList bookList){
}
所以干脆提供一个接口,让每一个操作都实现这个接口,然后重写work方法*/
public interface IOperation {//提供一个接口,默认它是一个抽象方法
void work(BookList bookList);
}
ReturnOperation的实现
import com.xiaoba.book.BookList;
import java.util.Scanner;
/**
* Description:归还操作
*/
public class ReturnOperation implements IOperation{
@Override
public void work(BookList bookList) {
System.out.println("归还图书");
Scanner scanner=new Scanner(System.in);
System.out.println("请输入要归还图书的名字:");
String name=scanner.nextLine();
//还书之前需要先遍历一下查看要还的书是否存在
for(int i=0;i< bookList.getUsedSize();i++){
Book book=bookList.getBook(i);//i号下标
if(book.getName().equals(name)){//拿到书之后,判断当前book的name和你输进来的这个书的name是否一致
book.setBorrowed(false);
System.out.println("归还成功!");
return;
}
}
System.out.println("没有你要归还的书籍");
}
}
3、创建用户相关的类
先创建 package user
创建 User 类, 这是一个抽象类
package com.xiaoba.user;
import com.xiaoba.book.BookList;
import com.xiaoba.operation.IOperation;
/**
* Description: User 类是一个抽象类, 每个子类需要做两件事情
1. 初始化对应的操作数组
2. 实现 Menu 菜单
*/
public abstract class User {
protected String name;
protected IOperation[] operations;//通过 protected定义一个 operations数组,
public User(String name){
this.name=name;
}
public abstract int menu();//给User提供一个菜单方法
public void doOperation(BookList bookList,int choice){//提供一个doOperation方法,传过来之后发现choice是几
this.operations[choice].work(bookList);//就表明这个数组的几号下标,跳到(Admin或NormalUser)下标所对应的对象,然后调用这个对象的work方法
}
}
创建普通用户类, 是 User 的子类.
package com.xiaoba.user;
import com.xiaoba.operation.*;
import java.util.Scanner;
/**
* Description:普通用户
*/
public class NormalUser extends User{//NormalUser继承User就把name拿过来了
public NormalUser(String name) {
super(name);//调用父类(User)的带有一个参数的构造方法
this.operations=new IOperation[]{//NormalUser普通用户继承了User,所以它就拥有了这些操作
new ExitOperation(),
new FindOperation(),
new BorrowOperation(),
new ReturnOperation()
};
}
//NormalUser需要实现一下menu方法
@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("================");
System.out.println("请输入您的选择:");
//看到菜单之后输入数据
Scanner scanner=new Scanner(System.in);
int choice=scanner.nextInt();
return choice;
}
}
创建管理员用户类
package com.xiaoba.user;
import com.xiaoba.operation.*;
import java.util.Scanner;
/**
* Description:管理员
*/
public class Admin extends User {//Admin继承User就把name拿过来了
public Admin(String name){
super(name);//调用父类(User)的带有一个参数的构造方法
this.operations=new IOperation[]{//Admin管理员继承了User,所以它就拥有了这些操作
new ExitOperation(),
new FindOperation(),
new AddOperation(),
new DelOperation(),
new DisplayOperation()
};
}
//Admin需要实现一下menu方法,这样一来子类和父类就都有menu了
@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("================");
System.out.println("请输入您的选择:");
//看到菜单之后输入数据
Scanner scanner=new Scanner(System.in);
int choice=scanner.nextInt();
return choice;//返回选择的值
}
}
4、测试
package com.xiaoba;
import com.xiaoba.book.BookList;
import com.xiaoba.user.Admin;
import com.xiaoba.user.NormalUser;
import com.xiaoba.user.User;
import java.util.Scanner;
/**
* Description:图书管理系统,面向对象编程,搭建框架,封装、调用....
*/
public class TestMain {
public static User login(){//设置一个登录,返回值是User
Scanner scanner=new Scanner(System.in);
System.out.println("请输入您的姓名:");
String name=scanner.nextLine();
System.out.println("请输入您的身份:(1代表管理员,2代表普通用户)");//根据不同的数字返回不同的对象,
//为什么要返回不同的对象呢?因为对象不一样,所打印的菜单也不一样
int chioce=scanner.nextInt();//定义一个chioce判断是1还是2
if(chioce==1){//如果是管理员,返回Admin(),管理员对象
return new Admin(name);//login的返回值是User,通过User来接收,发生了向上转型
}else {//如果是普通用户。返回NormalUser()
return new NormalUser(name);//想要将name写进去需要给 NormalUser提供构造方法,Admin也是如此
}
}
public static void main(String[] args) {
//1、准备书籍
BookList bookList = new BookList();//调用BookList不带有参数的构造方法,将书籍弄进来
//2、登录
User user = login();//user可能会指向管理员也可能会指向普通用户,引用谁的对象就调用谁的菜单
while (true) {
int choice = user.menu();//通过user调用menu方法,通过你菜单打印出的选择的数来调用对应的方法
//选择完之后传给doOperation,然后跳到User类
user.doOperation(bookList, choice);//调用doOperation,第一个参数为bookList,第二个参数为choice
}
}
}
补充:接口和接口之间是扩展,类和接口之间是实现。