图书管理系统(java) 代码展示和思路介绍 (9000字小长文)

前言:

这是本人基于面向对象的思想,利用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)

需要的可以自取

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值