如果当多个类需要进行键盘输入时过多的操作控制容易发生问题(其中不合适的代码如Scanner功能的关闭或者是nextLine()这种删除过多回车键可能会导致键盘输入数据功能无法正常进行),同时过多的键盘输入操作以造成代码阅读麻烦的影响。
在这样的问题背景下,修改代码的组成结构是最好的解决方法。更加清晰的代码功能分区除了可以避免上面的问题外,也大大提高了代码的可读性。接下来我们通过在简单的求解图形这一简单例子对代码分区功能进行实际操作。
这里我们将以一个项目来作为范本引出java多类的键盘输入:
已知,定义一个几何图形类,同时为这个类中添加私有化成员属性:图形颜色color、图形是否填充filled、图形的创建时间date(直接使用Date类获取系统时间),并且重写toString方法,输出形状,是否填充以及创建时间。(这里仅仅举例圆形与矩形)
当我们分析上面的例子会发现例子中所举的例子具有一些共同的属性(包括是否被填充,图形的颜色以及图形的创建时间;方法中的面积求解,周长求解),因而可以使用父类继承的方法来提高代码的效率,然而个体的独特属性也是需要吗我们手动输入的(半径,矩形的长和宽)。集中输入的类的创建是必要的。
输入类:
package nuc.ss.Geometric;
import java.util.Scanner;
//构造一个类用于管理包内所有类的键盘输入操作
public class Input
{
private Scanner scanner;//用于读取键盘的扫描器对象
//构造函数用于初始化Scanner对象
public Input()
{
scanner = new Scanner(System.in);
}
//读取并返回一个浮点数,以此来提示用户输入
public float getFloat(String prompt)
{
System.out.println(prompt);//显示提示信息
return scanner.nextFloat(); //读取并返回浮点数输入
}
//关闭Scanner对象,同时释放资源
public void close()
{
scanner.close();
}
}
1、通过导入Scanner类用于读取键盘输入的数据
2、通过定义一个Scanner对象“scanner”用于读取键盘输入的数据
3、构造Input函数用于初始化“scanner”对象使其能够读取从键盘输入的数据
4、读取浮点数方法,构造getFloat方法,通过接收一个字符串参数‘prompt’同时返回一个浮点数来达到将‘prompt’的内容输出到控制台,同时读取到用户键盘输入的下一个浮点数值,并将该值返回。(这是输出类的重要组成部分)
5、最后将Scanner方法进行关闭
图形类(圆形类和矩形类的父类)的定义:
package nuc.ss.Geometric;
import java.time.LocalDate;
import java.util.Date;
public class Geometric
{
protected String color;
protected boolean filled;
protected LocalDate date;
public Geometric() {}
public Geometric(String color, boolean filled)
{
super();
this.color = color;
this.filled = filled;
this.date = LocalDate.now();
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public boolean isFilled() {
return filled;
}
public void setFilled(boolean filled) {
this.filled = filled;
}
public LocalDate getDate() {
return date;
}
public void setDate(LocalDate date) {
this.date = date;
}
public float getArea()
{
return 0;
}
public float getPerimeter()
{
return 0;
}
public float getDiameter()
{
return 0;
}
}
圆形类的定义:
package nuc.ss.Geometric;
public class Circle extends Geometric
{
private float r;
public Circle(String color, boolean filled, Input input)
{
super(color,filled);//调用父类的构造函数
System.out.print("请输入圆半径: ");
this.r = input.getFloat("");//获取圆的半径
}
@Override
public float getArea()
{
return 3.14f * r * r;
}
@Override
public float getPerimeter()
{
return 3.14f * r * 2;
}
@Override
public float getDiameter()
{
return r * 2;
}
}
在这个程序中我们需要手动输入圆的半径,因而在通过构造方法获得私有变量时,我们直接通过Input()方法对其进行赋值。
矩形类的定义:
package nuc.ss.Geometric;
public class Rectangle extends Geometric
{
private float length;
private float width;
//构造方法,这里为了能够实现矩形运行相关参数键盘输入的步骤,构造一个接口用于接受来自键盘输入类的相关参数
public Rectangle(String color, boolean filled, Input input)
{
super(color, filled);
this.length = input.getFloat("请输入长方形的长:");
this.width = input.getFloat("请输入长方形的宽:");
}
public float getLength() {
return length;
}
public void setLength(float length) {
this.length = length;
}
public float getWidth() {
return width;
}
public void setWidth(float width) {
this.width = width;
}
@Override
public float getArea()
{
return length * width;
}
@Override
public float getPerimeter() {
return (length + width) * 2;
}
}
矩形类与圆形类类似,这里不进行过多的阐述。
测试类:
package nuc.ss.Geometric;
import java.util.Scanner;
public class TestGeometric {
public static void main(String[] args)
{
Input input = new Input();
Rectangle rectangle = null;
Circle circle = null;
Scanner scanner = new Scanner(System.in);
while(true)
{
System.out.println("-----------------菜单-----------------");
System.out.println("------------1、创建矩形----------------");
System.out.println("------------2、创建圆形----------------");
System.out.println("------------3、显示矩形信息-------------");
System.out.println("------------4、显示圆形信息-------------");
System.out.println("------------5、退出---------------------");
System.out.println("");
int choice = scanner.nextInt();
switch(choice)
{
case 1:
rectangle = new Rectangle("红色", true, input);
break;
case 2:
circle = new Circle("黑白色", true, input);
break;
case 3:
if(rectangle != null)
{
System.out.println("矩形的面积为:" + rectangle.getArea());
System.out.println("矩形的周长为:" + rectangle.getPerimeter());
System.out.println("矩形的颜色为:" + rectangle.getColor());
System.out.println("矩形是否被填充:" + rectangle.isFilled());
System.out.println("矩形的创建时间为:" + rectangle.getDate());
}
else
{
System.out.println("请先创建矩形!!!");
}
break;
case 4:
if(circle != null)
{
System.out.println("该圆形图像的面积为:" + circle.getArea());
System.out.println("该圆形图像的周长为:" + circle.getPerimeter());
System.out.println("该圆形图形的直径为:" + circle.getDiameter());
System.out.println("该圆形图形的颜色为:" + circle.getColor());
System.out.println("圆形图像是否被填充:" + circle.isFilled());
System.out.println("该圆形图像的创建时间为:" + circle.getDate());
}
else
{
System.out.println("请先创建圆形图形!!!");
}
break;
case 5:
System.out.println("程序退出!!!");
scanner.close();
input.close();
System.exit(0);
default :
System.out.println("无效的选择,请重新输入!!!");
break;
}
}
}
}
测试类也同样,只需要声明一个Input对象,那么需要键盘输入数据的部分只需要引用Input方法即可。
通过上面这个例子的引用,大家大概发现将键盘输入部分抽象成一个类极大地提高了代码的效率,我们不需要在每个类重复定义键盘输入部分,也不用担心因为Scanner格式定义不统一而造成的运行错误。