图书管理系统——java基础(源码)后续引入数据库,Swing程序设计,支持关注!后续更新……

         学了java想要练手,图书管理系统这个项目非常适合你

项目需求大体想法:

能够查看书籍,借阅书籍,打印书籍等功能。输出姓名后能进入为普通用户模式或者管理员模式。

各类包之间协同合作之间关系讲解。

做这个项目的始终是为了对于刚学java的同学,在学完面向对象,和一部分类和枚举,异常学完之后就可以尝试了。

这个项目没有多高大,这不过是对java基础知识的巩固,没有Swing图形界面,和前端知识,也没有引入数据库的知识jdbc。但是毕竟是项目,难度还是有的,对于初学者来说既能巩固知识,又能拓展思维,学会这个项目,期末考试考个90+不成问题,而且对后期真正项目起到很好的帮助。

一 .整体思路

书籍类为书籍的封装信息,和返回信息。有书,也要有书架,书架就是存放书籍的具体信息。至于为什么会有书架和书籍类之分,那就与代码可维护性,功能分析有很好作用。对于接口,就是具体代码实现了,像打印书籍,归还书籍,停止退出系统,查找书籍,增加书籍,删除书籍。在上面我说过有普通用户和管理员之分,那么就有这两类,这两类是实现菜单打印,和连接接口的功能。

(1)书籍包

键一个book包

Book是书籍类

这是基本书籍封装信息:

package book;

public class Book {
    private String name; //书名
    private String author;  //作者
    private String dynasty;  //朝代
    private int price;  // 价格
    private boolean isBorrowed;      //是否借出
    private String 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 String getDynasty() {
        return dynasty;
    }

    public void setDynasty(String dynasty) {
        this.dynasty = dynasty;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public boolean isBorrowed() {
        return isBorrowed;
    }

    public void setBorrowed(boolean borrowed) {
        isBorrowed = borrowed;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

上面的方法你准备怎么写呢?不会一步一步敲出来把?!

①点击鼠标右键,弹出generate,点击

②弹出getter and setter,点击

进入之后全选后确定就会出现我们想要的方法了

上面是对Book类的部分代码,当我们有需要时再去修改,跟着我的思路来才是一个程序员思维提升的好方法。

BookList是书架类

书架类我们首先做的就是建立动态数组,为了存储书籍,这里用到了数组的知识。

package book;


public class BookList {
    //建立一个动态数组存放信息
    //书架存放Book里面的书籍信息,那么该书籍是Book数组
   // private Book[]books=new Book[10];这样做可维护性不高所以把10改成
    private static final int number=20;
    private Book[]books=new Book[number];
    private int usedSize;
    public BookList(){
        books[0]=new Book("三国演义","罗贯中","明代","小说",520);
        books[1]=new Book("红楼梦","曹雪芹","清朝","小说",521);
        books[2]=new Book("西游记","不知道","明代","小说",250);
        this.usedSize=3;

    }

在这段代码中开辟了存放20的数组,下面的代码则是对书架中书籍的具体化,但是,在Book类中我们没有构建有参的构造方法,所以要加上。

  public Book(String name, String author, String dynasty, String type, int price) {
        this.name = name;
        this.author = author;
        this.dynasty = dynasty;
        this.type = type;
        this.price = price;

    }

(2)用户包

新建一个userall1包

建一个User抽象类

package userall1;
import book.*;
import opera.IPinterfrance;


//抽象类---》用户
public abstract class User {
    //写一个姓名
    protected String name;  //子类无法继承
    public User(String name){
        this.name=name;
    }
    //写了一个抽象方法菜单
    public abstract int menu();
}

建一个AdminUser管理员子类

package userall1;
import opera.*;

import java.util.*;
//AdmiinUser是User的子类
public class AdminUser extends User{
    public AdminUser(String name) {
        super(name);
}

建一个NormalUser普通用户子类

package userall1;

import opera.*;

import java.util.Scanner;

public class NormalUser extends User{
    public NormalUser (String name){
        super(name);
}

建立用户包的目的是为了区分管理员还是普通用户,并在本类中实现特定的功能。到这里代码还没有完全实现,思路要一步一步来,这里这不过是输入名字后,保存名字信息。

(三)主函数

程序的开始是主函数,代码就是在主函数开始调试的,当你不明白带代码是你就要从主函数一步一步开始分析。

先对主函数进行分析大体了解流程,接口中的具体实现方法最后看。因为他对全局影响不大。

在主函数中写一个登录方法

public class Main {
    //写一个登录类,返回值是User,请输入你的名字,选择身份
    //static为什么要用static与后面有关
    public static User login() {
        System.out.println("请输入你的姓名:");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();//输入字符串scanner.nextLine()
        System.out.println("请输入你的身份:1-》管理员 2-》普通用户");
        int choice = scanner.nextInt();
        if (choice == 1) {
            return new AdminUser(name);  //下面子类通过父类继承
        }
        if (choice == 2) {
            return new NormalUser(name);
        } else {
            System.out.println("输入错误!");

            return  login();

        }

    }

主方法里面要调用登录方法。

    public static void main(String[] args){
            User user = login();  //login()返回后是new AdminUser(name)父类通过子类实例化
            BookList bookList=new BookList();
            while(true)
            {
                int choice=user.menu();
                user.dowork(choice,bookList);

            }


        }
    

在主方法中我们看到user.menu(),所以user中要有抽象方法menu。dowork,而dowork方法是从user里调用的,目的是为了什么呢?我们加上代码

menu

user:

管理员具体菜单代码:

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.退出系统");
        
}

普通用户菜单代码:

    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.退出系统!");
}

光有菜单还不行,还要输入数字,输入数字后转接到具体实现类,那么就要再一次引入数组,通过数组下标来实现接口连接

在user引入:

在管理员类普通用户类中还要引入:

this.ioPerations = new IOPeration[]{//引用,这边用super也可以,因为这里没有同名的,不需要做区分。用this最好
                new ExitOperation(),
                new FindOperation(),
                new BrrowOperation(),
                new ReturnOperation(),     //为什么会放在子类因为子类接口不相同
                //以动态方式申请内存。拿到变量后,我们就给他们分配内存
        };

具体实现代码:

user:

普通用户和管理员都要在菜单下面加入输入数字语句:

      Scanner scanner=new Scanner(System.in);
        int choice=scanner.nextInt();
        return choice;

(四)接口实现包

建一个接口Ipinterfrance,为了实现各个功能的。

package opera;

import book.BookList;

import java.sql.SQLException;

//接口实现普通用户和管理员的功能
public interface IOPeration {
    //抽象方法功能是针对图书的
    void work(BookList bookList) throws ClassNotFoundException, SQLException;
}

二 .具体接口代码

(1)展示图书

package opera;
import book.*;
public class Showopera implements IPinterfrance{
    public void work(BookList bookList){   //传入图书变量
        System.out.println("展示图书!");
        int current=bookList.getUsedSize();
        for(int i=0;i<current;++i)
        {
            System.out.println(bookList.getBooks(i));

        }
    }


}

(2)增加图书

package opera;
import book.*;

import java.sql.*;
import java.util.*;
public class AddOperation implements IOPeration{


    //重写方法
    @Override
    public void work(BookList bookList) throws ClassNotFoundException, SQLException {
        System.out.println("新增图书!");
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入新增图书名字:");
        String name=scanner.nextLine();
        System.out.println("请输入新增图书作者:");
        String auther=scanner.nextLine();
        System.out.println("请输入新增图书价格:");
        int price=scanner.nextInt();
        Scanner scanner2=new Scanner(System.in);
        System.out.println("请输入新增图书类型:");
        String type=scanner2.nextLine();
       System.out.println("请输入新增图书作者朝代:");
       String dynasty=scanner2.nextLine();
 Book book=new Book(name,auther,dynasty,price,type);
        int currentSize= bookList.getUsedSize();
        for(int i=0;i<currentSize;++i){
            Book temp=bookList.getBooks(i);  //为什么会不同?? temp不行
            if(temp.getName().equals(name)){//判断查找图书名字是否相同
                System.out.println("已经有这本书了");
                return;
            }
        }
        bookList.setBooks(book);
        System.out.println("新增图书成功");
        //新图书+1
        bookList.setUsedSize(currentSize+1);
    }
}

这里的setBooks是书架类里面新增图书的方法:

(3)停止系统

停止系统非常简单,就是:

package opera;

import book.BookList;

public class ExitOperation implements IOPeration{
    @Override
    public void work(BookList bookList) {
        System.out.println("退出系统!");
        System.exit(0); //退出系统
    }
}

(4)借阅系统

package opera;

import book.BookList;
import java.util.*;
import book.*;
public class BrrowOperation implements IOPeration{
    @Override
    public void work(BookList bookList) {
        System.out.println("借阅图书");
        System.out.println("请输入要借阅的图书");
        Scanner scanner=new Scanner(System.in);
        String name=scanner.nextLine();
        int curentSize= bookList.getUsedSize();
        int x=1;
        for(int i=0;i<curentSize;i++){
            Book temp=bookList.getBooks(i);
            if((temp.getName().equals(name))&&!temp.isBorrowed()){  //
                {

                    temp.setBorrowed(true);
                    x=0;
                    System.out.println("借阅成功!");
                    return;
                }
            }
        }
        if(x==1){
            //写了个判断条件让我想到了冒泡排序
            System.out.println("没有该图书");
        }

    }
}

(5)归还图书

package opera;

import book.BookList;
import java.util.*;
import book.*;

public class ReturnOperation implements IOPeration{
    @Override
    public void work(BookList bookList) {
        System.out.println("归还图书!");
        System.out.println("请输入要归还的图书名字:");
        Scanner scanner=new Scanner(System.in);
        String name=scanner.nextLine();
        int curentSize= bookList.getUsedSize();
        for(int i=0;i<curentSize;i++){
            Book temp=bookList.getBooks(i);
            if((temp.getName().equals(name))&&temp.isBorrowed()){
                {
                    temp.setBorrowed(false);//变成归还状态false
                    System.out.println("归还成功!");
                    return;
                }
            }
        }


    }
}

(6)查找书籍

package opera;

import book.*;

import java.util.Scanner;

public class FindOperation implements IOPeration{
    @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.getBooks(i);
            if(book.getName().equals(name))  //判断书籍是否相同
            {
                System.out.println("找到了");
                System.out.println(book);
                return;
            }

        }
        System.out.println("没有这本书");

    }
}

(7)删除书籍

package opera;

import book.*;
import java.util.*;
public class DelOperation implements IOPeration{
    @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;
        //删除的思路很简单就是减小下标很粗暴
        for(int i=0;i<currentSize;i++){
            Book temp=bookList.getBooks(i);
            if(temp.getName().equals(name))
            {
                index=i;
                break;
            }
            for(int j=index;j<currentSize;j++)
            {
                Book book=bookList.getBooks(j+1);
                bookList.setBooks(j,book);  //把上面的数放到该位置为以后-1做铺垫
            }
        }


        bookList.setUsedSize(currentSize-1);//修改size值
        bookList.setBooks(currentSize-1,null);//因为删除的是对象,所以把地址置为null,就没有人引用了

    }

}

三 .疑难分析(看了5k点赞的看不懂的这里都有详细讲解

如果对这个项目很熟悉的话,直接看我的源码和疑难分析。

这段代码就是显示代码执行的,通过书架类中getbooks方法调用

如果对这个项目有所疑问请私信我,大家一定要捋一下代码,不会的地方私信我或者在评论区留言我一定会给大家回复!!!

四 .源码展示

主方法代码:

book包

Book类

package book;

public class Book {


    //书的名字,类型,作者,价格,是否借出
    private String name;
    private String author;
    private double price;
    private boolean isBorrowed;//是否借出
    private String type;
//此处点击鼠标,generate +Getter+Setter+全选
    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 double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public boolean isBorrowed() {
        return isBorrowed;
    }

    public void setBorrowed(boolean borrowed) {
        isBorrowed = borrowed;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
    //写一个构造方法不是特别明白
   public Book(String name,String author,double price,String type){
        this.author=author;
        this.name=name;
        this.type=type;
        this.price=price;

   }
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                ", type='" + type + '\'' +
                ", isBorrowed=" +(isBorrowed==true?"    已借出":"    未借出") +
                '}';
    }
    }

BookList类

package book;
import java.sql.*;
//写一个书架
public class BookList {

    //写数组 数据类型[]变量名=new 数据类型[大小]
    //private Book[]books=new Book[10];
    //上面的写法会可写性不高
    private static final int DEFAULT_SIZE=10;
    private Book[]books=new Book[DEFAULT_SIZE];
    private int usedSize;
    //虽然可以在类中直接初始化变量,但不定义构造方法可能会导致初始化逻辑分散
    // 和不清晰。构造方法提供了一种清晰、集中的方式来初始化对象的状态,
    // 这对于保持代码的组织、可读性和可维护性至关重要。
    public BookList(){
        books[0]=new Book("三国演义","罗贯中",55,"小说");
        books[1]=new Book("红楼梦","曹雪芹",50,"小说");
        books[2]=new Book("三国志","陈寿",58,"史书");
        this.usedSize=3;
    }

    public Book getBooks(int pos) {
        return this.books[pos];
    } //显示数据
    //记录当前数组有几本书
    //记录当前数组


   public void setBooks(Book book){
        this.books[usedSize]=book;
    } //通过这个方法增加书籍到这里面
    public void setBooks(int pos,Book book) {
        this.books[pos] = book;
    }


    public int getUsedSize() {
        return usedSize;
    }

    public void setUsedSize(int usedSize) {
        this.usedSize = usedSize;
    }



}

user包

管理员类

package users;

import java.util.Scanner;
import opera.*;
public class AdminUser extends User{
    public AdminUser(String name){
        super(name);
        this.ioPerations=new IOPeration[]{//引用,这边用super也可以,因为这里没有同名的,不需要做区分。用this最好
                new ExitOperation(),
                new FindOperation(),
                new AddOperation(),
                new DelOperation(),
                new ShowOperation()    //难于理解
        };
        }
    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("请输入序号:");
        Scanner scanner=new Scanner(System.in);
        int choice=scanner.nextInt();
        return choice;
    }
}

普通用户类

package users;

import java.util.Scanner;
import opera.*;//包里面全部调用
public class NormalUser extends User{
    public NormalUser(String name) {
        super(name);
        //动态开辟数组
        this.ioPerations = new IOPeration[]{//引用,这边用super也可以,因为这里没有同名的,不需要做区分。用this最好
                new ExitOperation(),
                new FindOperation(),
                new BrrowOperation(),
                new ReturnOperation(),     //为什么会放在子类因为子类接口不相同
                //以动态方式申请内存。拿到变量后,我们就给他们分配内存
        };
    }
    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("请输入序号:");
        Scanner scanner=new Scanner(System.in);
        int choice=scanner.nextInt();
        return choice;
    }
}

User抽象类

package users;
import opera.*;
import book.*;

import java.sql.SQLException;

public abstract class User { //抽象类
    protected String name; //不能为私有,否则管理员类或者普通类无法继承
    protected IOPeration[] ioPerations;//定义了数组
    //构造方法
    public User(String name){
        this.name=name;
    }
    public void doWork(int choice, BookList bookList) throws SQLException, ClassNotFoundException {//通过选择的操作,去选择执行数组下的哪个操作
        this.ioPerations[choice].work(bookList);
    }

    public abstract int menu();
}

接口

package opera;

import book.BookList;

import java.sql.SQLException;

//接口实现普通用户和管理员的功能
public interface IOPeration {
    //抽象方法功能是针对图书的
    void work(BookList bookList) throws ClassNotFoundException, SQLException;
}

具体代码上面已经给出不在重复展现

  • 41
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值