什么是面向对象?
1.找到对象
2.创建对象
3.实现对象
我们想要实现一个能分别服务于借阅者和管理员的图书管理系统
在Book类里面定义属性,构造属性方法,getter和setter,还有打印用的toString方法重写
//Book.java
package 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=" + isBorrowed +
'}';
}
}
BookList类同理,设置图书列表和数量
package Book;
public class BookList {
private Book[] books;
private int usedSize;//记录当前书架上实际存放的书的数量
public BookList() {
this.books = new Book[10];//初始化后全都是null
this.books[0] = new Book("三国演义","罗贯中",10,"小说");
this.books[1] = new Book("西游记","吴承恩", 9, "小说");
this.books[2] = new Book("红楼梦","曹雪芹", 19, "小说");
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 book){
books[pos] = book;
}
}
为了方便认出是管理员还是借阅者,我们设置一个IOPeration的接口来组织这些功能。
初始化功能,以AddOperation类为例
package operation;
import Book.BookList;
public class AddOperation implements IOPeration {
@Override
public void work(BookList bookList){
System.out.println("新增图书!");
}
}
//User.java
package user;
public class User {
protected String name;//只要User在user包底下用
public User(String name){
this.name = name;
}
}
借阅者和管理员都要继承于这个类
//NormalUser类
public void menu(){
System.out.println("***********************");
System.out.println("1.查找图书");
System.out.println("2.借阅图书");
System.out.println("3.归还图书");
System.out.println("0.退出系统");
System.out.println("***********************");
}
//AdminUser类
public void 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("***********************");
}
新建一个main的大类,真正测试都是在main函数里面实现的
//main.java
public static User login(){
System.out.println("请输入你的姓名:");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
System.out.println("请输入你的身份,1:管理员 2:普通用户-->");
int choice = scanner.nextInt();
if(choice == 1){
//管理员
return new AdminUser(name);//向上转型给到User
}else {
//普通用户
return new NormalUser(name);
}
}
public static void main(String[] args) {
//user指向哪个对象就看返回值是什么?
User user = login();
user.menu();//因为User里面么有menu方法,所以需要去User里面申明一下
}
去User申明menu方法时,menu其实没有具体实现,所以是一个抽象方法,而User类因为涵盖抽象方法,也就变成了一个抽象类
//User.java
package user;
//有抽象方法,这个类就变成了抽象类
public abstract class User {
protected String name;//只要User在user包底下用
public User(String name){
this.name = name;
}
public abstract void menu();//没有具体实现就是一个抽象方法
}
创建完menu后要提供给用户选择,NormalUser类的menu()如下,AdminUser类同理
//NormalUser.java,记住这里因为输入的选择类型,要改成int
public int menu(){
System.out.println("***********普通用户************");
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);
System.out.println("请输入你的操作:");
int choice = scanner.nextInt();
return choice;
}
//User类记得改类型
public abstract int menu()
现在系统初步构建好了,我们知道了user指向的是哪个对象,而且可以打印菜单并且提供操作选择
接下来要让他输入数字就能进行该数字对应的操作
首先我们在User类里面申明一个操作数组
protected IOPeration[] ioPerations;
接着在普通用户和管理员类里面分别把操作类添加进去
//NormalUser
public NormalUser(String name) {
super(name);
this.ioPerations = new IOPeration[]{
new ExitOperation(),
new FindOperation(),
new BorrowOperation(),
new ReturnOperation()
};
}
//AdminUser
public AdminUser(String name) {
super(name);
this.ioPerations = new IOPeration[]{
new ExitOperation(),
new FindOperation(),
new AddOperation(),
new DelOperation(),
new ShowOperation()
};
}
然后返回User类,定义一个能返回操作名称的方法
public void doOperation(int choice, BookList bookList){
ioPerations[choice].work(bookList);//ioPerations是书籍操作的集合哦
}
然后写进main里面,看user指向哪个对象就调用哪个
package operation;
import Book.Book;
import Book.BookList;
public class ShowOperation implements IOPeration {
@Override
public void work(BookList bookList){
System.out.println("打印图书!");
int currentSize = bookList.getUsedSize();
for (int i = 0; i < currentSize; i++) {
Book book = bookList.getBook(i);
System.out.println(book);
}
}
}
现在运行一下看看
isBorrowed这里false可视化不行,用户看不懂,我们要改一下当时重写的toString的方法
//Book.java
@Override
public String toString() {
return "book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
", type='" + type + '\'' +
((isBorrowed == true) ? " 已经借出" : " 未被借出") +
'}';
public class FindOperation implements IOPeration {
@Override
public void work(BookList bookList){
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.getBook(i);
if (book.getName().equals(name)){
System.out.println("找到了这本书,信息如下:");
System.out.println(book);
return;
}
}
System.out.println("没有找到这本书!");
}
}
在Book钟有四个属性,我们需要用键盘输入书的成员信息才能变成书的对象
输入信息过后,检查书架满了没,没满就默认把这本书放到队列中最后一本书的后面
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 currentSize = bookList.getUsedSize();
//检查有没有这本书
for (int i = 0; i < currentSize; i++) {
Book book1 = bookList.getBook(i);
if(book1.getName().equals(name)){
System.out.println("有这本书,不进行存放了!");
return;
}
}
//检查书架能不能放得下
if(currentSize == bookList.getBooks().length){
System.out.println("书架满了!");
}else{
bookList.setBook(currentSize,book);
bookList.setUsedSize(currentSize+1);
}
}
补充方法
//BookList
public void setBook(int pos, Book book){
books[pos] = book;
}
public Book[] getBooks(){
return books;
}
一开始图书列表长这样
找到有没有这本书,从后往前覆盖,将最后一本书进行置空
for (int i = 0; i < usedSize; i++){
Book[i] = Book[i+1];
}
public void work(BookList bookList){
System.out.println("删除图书!");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你要删除的图书");
String name = scanner.nextLine();
int pos = -1;
//找到有没有这本书
int currentSize = bookList.getUsedSize();
int i = 0;
for (; i < currentSize; i++) {
Book book = bookList.getBook(i);
if(book.getName().equals(name)){
pos = i;
break;
}
}
if (i == currentSize){
System.out.println("没有你要删除的图书!");
return;
}
//开始删除
int j = pos;
//从后往前覆盖
for (; j < bookList.getUsedSize()-1; j++) {
//[j] = [j+1]
Book book = bookList.getBook(j+1);
bookList.setBook(j,book);
}
//将最后一本书置空
bookList.setBook(j,null);
bookList.setUsedSize(currentSize-1);
}
借阅BorrowOperation和归还其实差不多,只展示借阅的代码
@Override
public void work(BookList bookList){
System.out.println("借阅图书!");
/**
* 1.你要借阅什么书
* 2.要借阅的书有没有
* 3.借阅的方式是什么?
*/
Scanner scanner = new Scanner(System.in);
System.out.println("请输入要借阅的书:");
String name = scanner.nextLine();
int currentSize = bookList.getUsedSize();
for (int i = 0; i < currentSize; i++) {
Book book = bookList.getBook(i);
if(book.getName().equals(name)){
book.setBorrowed(true);
System.out.println("借阅成功");
System.out.println(book);
return;
}
}
System.out.println("借阅的图书不存在");
}
当前问题:
1.没有持久化存储(上一次加的第二次再运行程序就没了)
2.当前用的只是数组,数组占用内存,一关闭内存销毁数组的内容也没了
方案:
1.存到文件里面 2.存到数据库中
后期可以用spring相关的+各种框架+redis