就像使用C语言写代码一样。比如要用C语言写一个小游戏的代码,我们的逻辑实现是在哪里实现的啊?是不是在一个test.c源文件里面啊?没错,就是的!在之前的文章里,我说过我定义的Main函数就像C语言里的test.c文件一样!所以,为了不打自己的脸。那我便在main函数里面实现我的图书管理系统的逻辑。
目录
逻辑实现:
第一步:登录界面
第二步:菜单的实现
第三步:增,删,查,显示等操作方法的实现和调用
方法实现:
逻辑实现:
第一步:登录界面
就像我们在日常生活中使用其它的系统有界面一样,为了使我们的图书馆管理系统更好的使用我们就需要有一个登录界面。
我的界面是这样的:
登录方法:landing
package User;
import java.util.Scanner;
import Library.Booklist;
public class Main {
public static User landing() {//登录界面的方法
System.out.println("请输入你的名字:>");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
System.out.println("请选择:0->普通用户,1——>管理员");
int choice = scanner.nextInt();
if(choice == 0 ) {
return new NormalUser(name);
}
else {
return new AdminUser(name);}
}
public static void main(String[] args) {
Booklist booklist = new Booklist();//准备数据
User user = landing();//用来选择登录那个界面的
}
}
说明:
1.这里最关键的一点是什么呢?其实是landing方法的返回类型!也就是这个:
可以看到这里的返回类型是User!为什么要使用User来作为返回类型呢?是因为User是AdminUser与NormalUser的父类!父类?父类又能如何呢?其实这是因为我写这段代码时这个登陆的方法是为了先让使用者选择身份,所以我们在登陆时就要有AdminUser与NormalUser两种不同的界面选择!所以为了兼容AdminUser与NormalUser于是我就使用了这两者的父类User来作为返回类型!
2.接收也要用User类型的变量来接收
第二步:菜单的实现
经过上述代码,现在我能实现的效果就是这样的:能输入一个名字,能选择一个身份。
但是,我们要的是这样的:
一步一步来,先加个菜单:
首先来设想一下,菜单是用来干吗的?菜单吗,选择的呗!那我们该如何选择呢?想一下当初用C语言写的游戏,无一例外都是用数字来进行选择的!所以,这个菜单的返回类型就是int型,我们在main方法里面便用int 型的变量来接收返回值,于是我们在main方法里面就多加了一条语句:
有了设想,现在就可以来实现这个菜单了:
先在User父类里定义一个抽象方法menu(),返回类型为int。但是抽象方法只能放在抽象类里边,所以User父类就被迫变成一个抽象类了!
代码:
package User;
public abstract class User {
protected String name;
public User(String name) {
// TODO Auto-generated constructor stub
this.name = name;
}
public abstract int menu();
}
说明:可能大家对这个操作会有疑问:
1.为什么要用抽象类呢?这是因为你用了抽象方法menu()!
2.为什么要用抽象方法呢?这是因为menu()这个方法是不用在User父类中具体实现的。
3.既然不用实现那我们为什么要搞出这么个玩意呢?这是因为我们在main方法中就是用User user来调用menu的,如果User(父类)没有menu()这个方法,那user将会报错!
好了,解释完毕!现在来看看menu()方法的具体实现:
AdminUser中:
package User;
import java.util.Scanner;
public class AdminUser extends User{
public AdminUser(String name) {
// TODO Auto-generated constructor stub
super(name);//先帮父类构造
this.name = name;//再自己构造
}
public int menu() {
System.out.println("欢迎 "+name+"来到图书管理系统");
System.out.println("*******************************");
System.out.println("0.退出系统");
System.out.println("1.添加图书");
System.out.println("2.移除图书");
System.out.println("3.查找图书");
System.out.println("4.显示图书");
System.out.println("*******************************");
System.out.println("请选择你的操作");
Scanner scanner = new Scanner(System.in);
int choice = scanner.nextInt();
return choice;
}
}
NormalUser类中:
package User;
import java.util.Scanner;
public class NormalUser extends User{
public NormalUser(String name) {
// TODO Auto-generated constructor stub
super(name);
this.name = name;
}
public int menu() {
System.out.println("欢迎 "+name+"来到图书管理系统");
System.out.println("*******************************");
System.out.println("0.退出系统");
System.out.println("1.借阅图书");
System.out.println("2.归还图书");
System.out.println("3.查找图书");
System.out.println("4.显示图书");
System.out.println("请选择你的操作");
Scanner scanner = new Scanner(System.in);
int choice = scanner.nextInt();
return choice;
}
}
第三步:增,删,查,显示等操作方法的实现和调用
在介绍搭建图书管理系统框架的那篇博客当中我已经将图书管理系统中的各种方法粗略的讲了一遍了。现在我就来实现一下这些方法!但是方法实现了又能怎样呢?有了方法要用才是真的!所以我们先来讲讲如何用我们的选择调用这些方法!
思路:
还记得我说这些方法就是一个多态,但是他们都间接继承于IOperation这个接口。所以我们是否能定义一个IOperation接口型的数组来通过下标来对这些方法来进行调用呢?答案是当然可以的。
第一步:User(父类)中
第二步:在AdminUser(子类)中
第三步:在NormalUser(子类)中
调用:
在搞清楚如何调用并且做了相关的准备以后我们就可以来写调用方法了
调用方法:doOperation
这个方法要定义在User里,为什么呢?这是因为我们在main方法里面是要用User类型的user来对这个方法来进行使用的,假如我的User父类里面没有这个方法那还怎么使用这个方法呢?所以这个方法就要定义在User(父类)中。
代码:
public void doOperation(int choice,Booklist booklist) {
ioperations[choice].work(booklist);//利用之前定义的接口数组来访问各种操作方法
}
方法实现:
1.AddOperation
代码:
package Operation;
import java.util.Scanner;
import Library.Booklist;
public class AddOperation implements IOperation{
public void work(Booklist booklist) {//重写方法,使这个方法变为Addoperation的方法
System.out.println("添加图书!");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你要添加的图书的名字:>");
String name = scanner.nextLine();
System.out.println("请输入你要添加的图书的类型:>");
String type = scanner.nextLine();
System.out.println("请输入你要添加的图书的作者:>");
String author = scanner.nextLine();
System.out.println("请输入你要添加的图书的价格:>");
int price = scanner.nextInt();
System.out.println("添加成功!");
}
}
2.DisplayOperation
代码:
package Operation;
import Library.Book;
import Library.Booklist;
public class DisplayOperation implements IOperation {
public void work(Booklist booklist) {
System.out.println("显示图书!");
int curSize = booklist.getSize();
for(int i = 0;i<curSize;i++) {
Book book = booklist.getPos(i);
System.out.println(book);
}
}
}
当然,这个代码要实现就要在原来的代码中添加一些细节的东西,三处细节:
因为我这里是使用遍历的方法来对每一本书的信息进行打印的。所以,我就要知道整个数组的长度。所以,原来的booklist类中就要有代表数组长度的变量和获取数组长度的方法,所以原来的代码就被多加了:
获取完长度以后,我们就要对一本书的各种信息进行打印了,一般是System.out.println(book)这样来打印的。所以我们要获取到每一本书,所以我们又要添加一个获取每一本书的方法:
但是很快你就会又发现一个错误:
打印出来了一堆奇奇怪怪的东西,为什么呢?没有重写呗。所以我们又要在Book这个类里面加一个重写的方法:
搞完收工!
3.DelOperation
package Operation;
import java.util.Scanner;
import Library.Book;
import Library.Booklist;
public class DelOperation implements IOperation {
public void work(Booklist booklist) {//重写方法,使work方法变成DelOperation的方法
Scanner scanner = new Scanner(System.in);
System.out.println("删除图书!");
System.out.println("请输入你要删除的图书的名字:>");
String name = scanner.nextLine();
int curSize = booklist.getSize();
int index = -1;
for(int i = 0;i<curSize;i++) {
Book book = booklist.getPos(i);
if(name.equals(book.getName())) {
index = i;
break;
}
}
if(index == -1) {
System.out.println("没有你要删除的书!");
}
else {
for(int i = index;i<curSize-1;i++) {
Book book = booklist.getPos(i+1);
booklist.setBooks(book, i);
}
booklist.setSize(curSize-1);
booklist.setBooks(null, curSize);
System.out.println("删除成功!");
}
}
}
当然这个代码也要添加一些细节的东西,比如设置书架某一位置设置为下一本书东西的方法,setBooks:
当然,在删除完一本书以后书的数量就要减少,书的最后一个位置就要置空:
4.其它方法
其实在写完前面的几个方法以后其它的代码都很好写了,这里我就不写了!如果读者感兴趣的话可以自己思考一下来写那几个方法!