前言:
这是本人基于面向对象的思想,利用java写的,用于练习的图书管理系统,代码和框架存在借鉴,本人并无获取利益的考虑,旨在分享和记录知识
框架与思路
作为一个图书管理系统,我们可以将它分成这个几个对象
1.书
书可以分为书籍信息和书架,前者负责储存书的信息,后者如字面意思,负责向使用者展示有多少书籍
2.用户
用户分为管理员和普通用户,前者要进入,还需要设置密码
3.操作
管理员和用户需要有不同的操作权限吗,用于查阅,增加,显示,借书和还书等操作
具体框架如截图
框架图
这里有个习惯不要学,类名开头字母要大写哦
"书籍"包的代码
首先是book
package Book;
public class book
{
private String name;
private String author;
private int price ;
private String type;
private boolean isBorrowed;//是否已经被借出
@Override
public String toString() {
return "book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
", type='" + type + '\'' +
((isBorrowed==true?"已经被借出":"没有被借出"))+
'}';
}
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;
}
}
代码作用:
负责建立书籍的相关信息,为了体现的专业点(封装),我用了private
值得一提的是
((isBorrowed==true?"已经被借出":"没有被借出"))+
这里运用的三目运算符,来体现书籍是否被借走
然后是书架
首先给各位看看代码的效果
boolean 默认是false,所以状态是没有被借出
说白了,book类也是一种数据类型,我们自然可以用数组来保存它,数组真的很有用
代码
package Book;
import Book.book;
public class booklist
{
private book [] books;
private int usedsize;
public booklist()
{
this.books = new book[1000];
this.books[0]=new book("红楼梦","曹雪芹",20,"小说");
this.books[1]=new book("水浒传","施耐庵",20,"小说");
this.books[2]=new book("三国演义","罗贯中",21,"小说");
this.usedsize=3;
}
public int getUsedsize()
{
return usedsize;
// 获得数组大小
}
public void setUsedsize(int usedsize)
{
this.usedsize = usedsize;
//改变数组大小
}
public book getbook(int pos)
{
return books[pos];
// 负责展示书籍
}
public void setbook(int pos,book abook)
{
books[pos]=abook;
//放置书籍
}
}
用户包——个人认为的难点
用户分为普通用户和管理员,那么他们肯定有两套界面,
如图所示
public int menu ()
{
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("*********************");
System.out.println("请输入你的操作:");
Scanner sc=new Scanner(System.in);
int choice=sc.nextInt();
return choice;
}
public int menu ()
{
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("*********************");
System.out.println("请输入你的操作:");
Scanner sc = new Scanner(System.in);
int choice = sc.nextInt();
return choice;
}
我们需要一个父类
package User;
import Book.booklist;
import operation.WORK;
public abstract class Users
{
protected String name;
protected WORK[] Work;
public Users(String name) {
this.name = name;
}
@Override
public String toString() {
return "Users{" +
"name='" + name + '\'' +
'}';
}
public abstract int menu ();
public void Doop(int choice, booklist Booklist)
{
Work[choice].work(Booklist);
}
}
QE:为什么要数组?
AW:因为不同的操作类也是一种引用数据,可以存在数组里面,然后通过输入下标调用
(说人话:调用WORK数组下标为choice
的元素,实现其work方法)
在子类中重写
两个子类,代码分别如下
package User;
import operation.*;
import java.util.Scanner;
public class Nomaluser extends Users
{
public Nomaluser(String name)
{
super(name);
this.Work=new WORK[]{new Exitop(),new Findop(),new Borrowop(),new Returnop(),new Show()};
}
public int menu ()
{
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("*********************");
System.out.println("请输入你的操作:");
Scanner sc=new Scanner(System.in);
int choice=sc.nextInt();
return choice;
}
}
package User;
import operation.*;
import java.util.Scanner;
public class Adminuser extends Users
{
public Adminuser(String name)
{
super(name);
this.Work=new WORK[]{new Exitop(),new Findop(),new Addop(),new Deleteop(),new Show()};
}
public int menu ()
{
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("*********************");
System.out.println("请输入你的操作:");
Scanner sc = new Scanner(System.in);
int choice = sc.nextInt();
return choice;
}
}
操作包
增加操作
package operation;
import Book.book;
import Book.booklist;
import java.util.Scanner;
public class Addop implements WORK
{
@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 size=BOOKlist.usedsize;
for(int i=0;i<size;i++)
{
book temp=BOOKlist.getbook(i);
if(Book.equals(temp))
{
System.out.println("不能增加同样的书籍");
return;
}
}
BOOKlist.setbook(size,Book);
BOOKlist.setUsedsize(size+1);
}
}
值得注意的是结尾
BOOKlist.setbook(size,Book);
BOOKlist.setUsedsize(size+1);
我们先将新的Book放进去,然后再开辟一块新的空间
借阅操作
package operation;
import Book.book;
import Book.booklist;
import java.util.Scanner;
public class Borrowop implements WORK
{
@Override
public void work(booklist BOOKlist)
{
Scanner scanner=new Scanner(System.in);
System.out.println("输入借阅图书的书名");
String name=scanner.nextLine();
int size=BOOKlist.usedsize;
for(int i=0;i<size;i++)
{
book temp = BOOKlist.getbook(i);
if(temp.getName().equals(name)&&temp.isBorrowed()==false)
{
System.out.println("成功借出");
temp.setBorrowed(true);
return ;
}
}
System.out.println("没有找到这本书,应该没借走了");
}
}
值得注意的是,最好判断下这书到底有没有被借走.
退出操作
这没什么好说的
package operation;
import Book.booklist;
public class Exitop implements WORK
{
@Override
public void work(booklist Booklist)
{
System.out.println("退出系统,感谢您的使用");
System.exit(0);
}
}
删除操作——本人觉得最难的
这么操作有点像之前写顺序表的时候,如果你要删除一个数据,就让后面的数据依次顶替上来
然后让结尾的数据变为null
package operation;
import Book.book;
import Book.booklist;
import java.util.Scanner;
public class Deleteop implements WORK {
@Override
public void work(booklist Booklist)
{
Scanner scanner=new Scanner(System.in);
System.out.println("请输入你想删除的书籍的名字");
String name=scanner.nextLine();
int size=Booklist.getUsedsize();
int pd=0;
int flag=0;
for(int i=0;i<size;i++)
{
book temp= Booklist.getbook(i);
if(temp.getName().equals(name))
{
flag=i;
pd=-1;
break;
}
}
if(pd==0)
{
System.out.println("没有这本书,删除失败");
return ;
}
else
{
for(int j=flag;j<size;j++)
{
book temp= Booklist.getbook(j+1);//得到j+1位置的信息
Booklist.setbook(j,temp);//把信息放入j位置,实现交换
}
}
Booklist.setbook(size-1,null);//位置变成null;
Booklist.setUsedsize(size-1);//书架少一个位置
}
}
这里也体现一些方法的好处了,可以直接调用,省的自己写
归还操作
和借阅互补,没什么好说的
package operation;
import Book.book;
import Book.booklist;
import java.util.Scanner;
public class Returnop implements WORK
{
@Override
public void work(booklist Booklist)
{
System.out.println("请输入归还图书的名字");
Scanner scanner=new Scanner(System.in);
String name=scanner.nextLine();
int size=Booklist.getUsedsize();
for(int i=0;i<size;i++)
{
book temp=Booklist.getbook(i);
if(temp.getName().equals(name)&&temp.isBorrowed()==true)
{
temp.setBorrowed(false);
System.out.println("归还成功");
return ;
}
}
System.out.println("归还失败,没有这本书");
}
}
显示操作
package operation;
import Book.book;
import Book.booklist;
public class Show implements WORK
{
@Override
public void work(booklist Booklist)
{
System.out.println("显示图书");
int currents= Booklist.getUsedsize();
for(int i=0;i<currents;i++)
{
book Book = Booklist.getbook(i);
System.out.println(Book);
}
}
}
查找操作
比对名字就好了,也不难
package operation;
import Book.book;
import Book.booklist;
import java.util.Scanner;
public class Findop implements WORK
{
@Override
public void work(booklist Booklist)
{
System.out.println("输入你要查找的图书的name");
Scanner scanner=new Scanner(System.in);
String name=scanner.nextLine();
int size= Booklist.getUsedsize();
for(int i=0;i<size;i++)
{
book temp=Booklist.getbook(i);
if(temp.getName().equals(name))
{
System.out.println("找到了,信息如下");
System.out.println(temp);
return ;
}
}
System.out.println("没有找到!");
}
}
接口
接口也很关键,不然没法用数组把操作类串起来
package operation;
import Book.booklist;
public interface WORK
{
void work(booklist Booklist);
}
Main类
这个类,主要是就整合
import Book.booklist;
import User.Adminuser;
import User.Nomaluser;
import User.Users;
import java.util.Scanner;
class IncorrectPasswordException extends Exception {
public IncorrectPasswordException(String message) {
super(message);
}
}
public class Main {
public static boolean PassWord() throws IncorrectPasswordException {
System.out.println("请输入密码:");
Scanner scanner = new Scanner(System.in);
String password = scanner.nextLine();
if (password.equals("jsh")) {
return true;
} else {
throw new IncorrectPasswordException("密码错误!");
}
}
public static Users login() {
System.out.println("请输入你的姓名:");
Scanner sc = new Scanner(System.in);
String name = sc.nextLine();
System.out.println("请输入你的身份: 1.管理员 2.用户");
int chosen = sc.nextInt();
sc.nextLine(); // 清除换行符
if (chosen == 1) {
try {
if (PassWord())
{
System.out.println("正确,已进入");
return new Adminuser(name);
}
} catch (IncorrectPasswordException e)
{
System.out.print(e.getMessage());
System.out.println("请重试");
return null;
}
} else {
return new Nomaluser(name);
}
return null;
}
public static void main(String[] args) {
booklist Booklist = new booklist();
Users use;
while (true)
{
use = login();
if (use != null)
{
break;
}
}
while (true) {
int choice = use.menu();
use.Doop(choice, Booklist);
}
}
}
首先调用login,通过向上转型,来判断你该用那个子类
值得一提的是:
为了符合逻辑,我写了一个简易的密码方法,毕竟,怎么可能不用密码直接进入管理员系统
然后,调用Doop,我们已经写好了
还是那个解释
(说人话:调用WORK数组下标为choice
的元素,实现其work方法)
写在结尾
通过这个练习,笔者第一次体会到面向对象思想的好处,但是框架我也确实想不到,敢接网友的智慧吧!
补充:关于向上和向下转型的小心得
该代码同样也体现了继承和多态,我们使用向上转型以后,将方法也在父类里,就可以在子类中进行重写,从而实现多态,提高了代码的延展性和可读性.
当然,如果向上转型以后,需要调用子类独有的方法,那么就需要向下转型了
calljj/Call-JJ-java (gitee.com)
calljsh/Call-JJ-java (github.com)
需要的可以自取