1. 设计一个形状类Shape,方法:求周长和求面积
形状类的子类:Rect(矩形),Circle(圆形)
Rect类的子类:Square(正方形)
不同的子类会有不同的计算周长和面积的方法
解题思路:
-
计算三个形状类的周长和面积,周长与面积是他们共有的结果,可以单独写一个类进行结果接收,其他类继承父类
-
形状类定义各自的属性并封装,对属性提供get 和set 方法
-
有参构造方法(根据需求而定,这个场景使用有参构造,可以初始化实例时,直接给属性赋值)
-
重写父类方法(计算周长与面积)
package area;
public class Shape {
public double sum = 0; //周长
public double area = 0; //面积
public double getSum(){
return 0.0;
}
public double getArea(){
return 0.0;
}
}
package area;
public class Rect extends Shape{ //矩形
private double length;
private double wide;
public void setLength(double length) {
this.length = length;
}
public void setWide(double wide) {
this.wide = wide;
}
public double getLength() {
return length;
}
public double getWide() {
return wide;
}
public Rect(double length,double wide){
this.length = length;
this.wide = wide;
}
@Override
public double getSum() {
sum = 2 * (this.length + this.wide);
return sum;
}
@Override
public double getArea() {
area = this.length * this.wide;
return area;
}
}
package area;
public class Circle extends Shape { //圆
private final static double p = 3.1415926;
private double radius;
public Circle(double radius){
this.radius =radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
@Override
public double getSum() {
sum = 2 * p * radius;
return sum;
}
@Override
public double getArea() {
area = radius * radius * p;
return area;
}
}
package area;
public class Square extends Shape{ //正方形
private double sidelength;
public Square(double sidelength){
this.sidelength = sidelength;
}
public void setSidelength(double sidelength) {
this.sidelength = sidelength;
}
public double getSidelength() {
return sidelength;
}
@Override
public double getSum() {
sum = 4 * sidelength;
return sum;
}
@Override
public double getArea() {
area = sidelength * sidelength;
return area;
}
}
package area;
public class AreaTest {
public static void main(String[] args) {
Rect r = new Rect(4,5); //矩形
Circle c = new Circle(4.56); //圆
Square s = new Square(5.67); //正方形
r.getSum();
r.getArea();
System.out.println("矩形的周长:"+ r.getSum() +";矩形的面积:"+ r.getArea());
c.getSum();
c.getArea();
System.out.println("圆的周长:"+ c.getSum() +";圆的面积:"+ c.getArea());
s.getSum();
s.getArea();
System.out.println("正方形的周长:"+ s.getSum() +";正方形的面积:"+ s.getArea());
}
}
2. 设计一个台灯类(Lamp)其中台灯有灯泡类(Buble)这个属性,还有开灯(on)这个方法
设计一个灯泡类(Buble),灯泡类有发亮的方法,其中有红灯泡类(RedBuble)和绿灯泡类(GreenBuble),他们都继承灯泡类(Buble)一个发亮的方法
解题思路:
-
灯泡发光是一个事物的共同行为,可以作为父类,让具体的物品进行继承(使用抽象类而不是普通类,是因为发光的方法是需求必须要求实现的部分)
-
绿灯与红灯继承发光的方法并重写(每种灯发出光的方式或条件是不一样的,所以需要重写父类方法)
-
台灯打开开关,然后发光,除了需要电以外,他还需要一个灯泡,所以将灯泡的类实例化作为属性
-
灯泡作为父类,可以引用子类对象,最终Test类调用台灯开关ON(),并上传作为参数的灯泡(红灯与绿灯类),达到需求不同灯泡发出不同光的需求。
package lantern;
public abstract class Buble { //灯泡
public abstract String lampOn(); //开灯,灯泡发亮啦!!
}
package lantern;
public class RedBuble extends Buble{ //继承灯泡的发亮的方法,并重写
@Override
public String lampOn() {
return "红灯亮了!";
}
}
package lantern;
public class GreenBuble extends Buble{
@Override
public String lampOn() {
return "绿灯亮了!";
}
}
package lantern;
public class Lamp {
private Buble buble; //属性封装(一个类的属性可以是一个实例对象)
public Buble getBuble() { //提供读与写的方法
return buble;
}
public void setBuble(Buble buble) {
this.buble = buble;
}
public void on(Buble buble){ //传入Buble 类型的对象
if(buble instanceof GreenBuble){//instanceof 严格来说是Java中的一个双目运算符
String g = buble.lampOn(); //instanceof 用来测试一个对象是否为一个类的实例
System.out.println("打开台灯:"+ g);
}else if(buble instanceof RedBuble){
String r = buble.lampOn(); //父类调用子类重写方法
System.out.println("打开台灯:"+ r);
}
}
}
package lantern;
public class BubleTest {
public static void main(String[] args) {
Lamp l = new Lamp();
Buble r = new RedBuble(); //父类引用子类对象
Buble g = new GreenBuble();
l.on(r);
l.on(g);
}
}
3. 写一个程序,把若干各种类型的员工放在一个Employee数组里,写一个方法,打印出某月每个员工的工资数额
-
Employee:这是所有员工总的父类
-
属性:员工的姓名,员工的生日月份
-
方法:
-
double getSalary(int month) 根据参数月份来确定工资,如果该月员工过生日,则公司会额外奖励100元
-
SalariedEmployee:Employee的子类,拿固定工资的员工。属性:月薪
-
HourlyEmployee:Employee的子类,按小时拿工资的员工,每月工作超出160小时的部分按照1.5倍工资发放。属性:每小时的工资、每月工作的小时数
-
SalesEmployee:Employee的子类,销售人员,工资由月销售额和提成率决定。属性:月销售额、提成率
-
BasePlusSalesEmployee:SalesEmployee的子类,有固定底薪的销售人员,工资由底薪加上销售提成部分。属性:底薪。
-
-
要求:
-
写一个程序,把若干各种类型的员工放在一个Employee数组里,
-
写一个方法,打印出某月每个员工的工资数额。
注意:
-
要求把每个类都做成完全封装,不允许非私有化属性。
解题思路:
-
Employee类作为员工的基本信息,包含姓名、生日、薪资的属性
-
其他类(月薪、小时工、销售)分别继承父类信息,有销售底薪+提成的类继承销售提成的类,并实现各自的薪资的计算方式
-
通过getSalary方法进行调用和读取每月各自的薪资信息
-
这里用到了一个新实例,JDK8提供获的LocalDate类,取时间和写入时间更方便
-
要实现某个功能或需求,首先是要想清楚实现的方式和逻辑,脑子里要有个大概的框架,条理清晰,才不会被自己绕晕和想复杂(个人小感悟)
package employees;
import java.time.LocalDate;
public class Employee { //员工信息
private String name;
private LocalDate birthday;
public Employee(){ //默认构造(无参构造)
}
public Employee(String name, LocalDate birthday){ //类需要被集成,类中存在非默认构造需要手写默认构造
this.name = name;
this.birthday = birthday;
}
public void setName(String name) {
this.name = name;
}
public void setBirthday(LocalDate birthday) {
this.birthday = birthday;
}
public String getName() {
return name;
}
public LocalDate getBirthday() {
return birthday;
}
public double getSalary(int month){
return 0;
}
}
package employees;
import java.time.LocalDate;
public class HourlyEmployee extends Employee{ //按小时领取工资
private double hourLyEmp;
private int hours;
public HourlyEmployee(){ //一个类中一定存在一个无参的默认构造,不写会编译会报错
}
public HourlyEmployee(String name, LocalDate birthday,int hourLyEmp,int hours){
super(name, birthday);
this.hourLyEmp = hourLyEmp;
this.hours = hours;
}
public void setHourLyEmp(double hourLyEmp) {
this.hourLyEmp = hourLyEmp;
}
public double getHourLyEmp() {
return hourLyEmp;
}
public int getHours() {
return hours;
}
public void setHour(int hour) {
hours = hour;
}
@Override
public double getSalary(int month) {
double sum = 0.0;
if(this.getBirthday().getMonthValue() == month){
sum += 100;
}
if(hours <= 160){
sum += hours * hourLyEmp;
} else if(hours > 160){
sum += 160 * this.getHourLyEmp() + (this.getHours() - 160) * (this.getHourLyEmp() * 1.5);
}
return sum;
}
}
package employees;
import java.time.LocalDate;
public class SalariedEmployee extends Employee{ //拿固定工资
private double monthLysalary; //月薪
public double getMonthLysalary() {
return monthLysalary;
}
public void setMonthLysalary(double monthLysalary) {
this.monthLysalary = monthLysalary;
}
public SalariedEmployee(){
}
public SalariedEmployee(String name, LocalDate birthday, double monthLysalary){
super(name, birthday);
this.monthLysalary = monthLysalary;
}
@Override
public double getSalary(int month) {
double num = this.getMonthLysalary();
if(this.getBirthday().getMonthValue() == month){
num += 100;
}
return num;
}
}
package employees;
import java.time.LocalDate;
public class SalesEmployee extends Employee { //销售提成
private double monthlySales; //月销售额
private double commissionRate; // 提成率
public SalesEmployee(){
}
public SalesEmployee(String name, LocalDate birthday, double monthlySales, double commissionRate){
super(name,birthday);
this.monthlySales = monthlySales;
this.commissionRate = commissionRate;
}
public double getMonthlySales() {
return monthlySales;
}
public double getCommissionRate() {
return commissionRate;
}
public void setMonthlySales(double monthlySales) {
this.monthlySales = monthlySales;
}
public void setCommissionRate(double commissionRate) {
this.commissionRate = commissionRate;
}
@Override
public double getSalary(int month) {
double sum = 0.0;
if(this.getBirthday().getMonthValue() == month){
sum +=100;
}
sum +=this.getMonthlySales() * this.getCommissionRate();
return sum;
}
}
package employees;
import java.time.LocalDate;
public class BasePlusSalesEmployee extends SalesEmployee { //底薪 + 提成
private int baseSalary;
public BasePlusSalesEmployee(String name, LocalDate birthday, double monthlySales, double commissionRate, int baseSalary){
super(name, birthday, monthlySales, commissionRate);
this.baseSalary = baseSalary;
}
public int getBaseSalary() {
return baseSalary;
}
public void setBaseSalary(int baseSalary) {
this.baseSalary = baseSalary;
}
@Override
public double getSalary(int month) {
double sum = 0.0;
if (this.getBirthday().getMonthValue() == month) {
sum += 100; // + 生日奖金
}
sum += getBaseSalary(); // + 底薪
sum += this.getMonthlySales() * this.getCommissionRate(); // + 销售提成
return sum;
}
}
package employees;
import java.time.LocalDate;
public class EmployeeTest {
public static void main(String[] args) {
// LocalDate now = LocalDate.now(); jdk 8 新提供的方法,获取当前日期
// LocalDate.of(2018, 9, 24); jdk 8 写入日期
Employee [] employees = new Employee[4]; //除了new一个对象,我们还可以new一个数组
HourlyEmployee h = new HourlyEmployee("张三", LocalDate.of(1995,12,17),50,160);
SalariedEmployee s1 = new SalariedEmployee("李四",LocalDate.of(1994,11,17),5000);
SalesEmployee s2 = new SalesEmployee("王五", LocalDate.of(1995,12,17),10000,0.1);
BasePlusSalesEmployee b = new BasePlusSalesEmployee("张飞", LocalDate.of(1995,12,17),3000,0.1,10000);
employees[0] =h;
employees[1] =s1;
employees[2] =s2;
employees[3] =b;
for (Employee e:employees) {
System.out.println("姓名:"+ e.getName() +" "+ "薪资:" + e.getSalary(12) +" "+ "生日:"+e.getBirthday());
}
}
}
4. 完成以下要求,最终创建Test类,完成Test的操作要求
要求如下:
-
创建一个Animal动物类,要求有方法eat()方法,方法输出一条语句“吃东西”
-
创建一个接口A,接口里有一个抽象方法fly()
-
创建一个Bird类继承Animal类并实现接口A里的方法输出一条有语句“鸟儿飞翔”,重写eat()方法输出一条语句“鸟儿 吃虫”
-
在Test类中向上转型创建b对象,调用eat方法。然后向下转型调用eat()方 法、fly()方法
新知识点:
-
把子类对象直接赋给父类引用叫upcasting向上转型,向上转型不用强制转型,如:Father father = new Son()
-
把指向子类对象的父类引用赋给子类引用叫向下转型(downcasting),要强制转型,要向下转型,必须先向上转型为了安全可以用instanceof判断
-
如father就是一个指向子类对象的父类引用,把father赋给子类引用son 即Son son =(Son)father,其中father前面的(Son)必须添加,进行强制转换
-
-
upcasting 会丢失子类特有的方法,但是子类overriding 父类的方法,子类方法有效,向上转型只能引用父类对象的属性,要引用子类对象属性,则要写getter函数
-
向上转型的作用,减少重复代码,父类为参数,调有时用子类作为参数,就是利用了向上转型。这样使代码变得简洁,体现了JAVA的抽象编程思想
package Animal;
public class Animal {
public void eat(){
System.out.println("吃东西");
}
}
package Animal;
public interface A {
public abstract void fly();
}
package Animal;
public class Bird extends Animal implements A {
@Override
public void eat() {
System.out.println("鸟儿 吃虫");
}
@Override
public void fly() {
System.out.println("鸟儿在飞翔");
}
}
package Animal;
public class AnimalTest {
public static void main(String[] args) {
Bird b = new Bird();
b.eat(); //调用子类本身的方法
Animal a = new Bird(); //父类的引用指向了子类对象,子类对象转为父类。将子类的对象赋值给父类(向上转型)
a.eat();//多态,执行子类中的方法,体现了多态的特性,同一种事物在不同情形下所表现出来的不同状态,只针对方法,不针对成员变量
//eat()方法是子类重写父类方法(必须是父类的重写方法),所以可以调用。。调用子类中独有的方法就会报错,如a.fly();
Bird c = (Bird)a; //子类的引用指向了父类,父类对象转为子类。并将父类强制转换为子类对象(向下转型)
c.eat();
c.fly();
}
}
5. 按照以下场景要求,完成编码设计
-
创建一个Person抽象类
-
要求含有姓名(name)年龄(age)两个私有属性以及吃饭(eat) 和睡觉(sleep)两个抽象方法,并写出带参构造方法
-
-
创建学生(student)和工人(worker) 两个类,继承Person类
-
学生类多出了私有属性学号和学习方法(输出我爱学习)
-
工人类多出了私有属性工号和工作方法(输出我爱工作)
-
-
在主函数中创建学生和工人类 的实例对象,使用构造方法赋值,并输出所有属性和方法
package person;
public abstract class Person {
private String name;
private int age;
public Person(){
}
public Person(String name,int age){
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public abstract void eat();
public abstract void sleep();
}
package person;
public class Student extends Person{
private int number;
public void setNumber(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
public void study(){ //学习方法
System.out.println("我爱学习");
}
public Student(String name, int age,int number){
super(name,age);
this.number = number;
}
@Override
public void eat() {
}
@Override
public void sleep() {
}
}
package person;
public class Worker extends Person{
private int num;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public Worker(){
}
public Worker(String name,int age,int num){
super(name,age);
this.num = num;
}
public void working(){ //工作方法
System.out.println("我爱工作");
}
@Override
public void eat() {
}
@Override
public void sleep() {
}
}
package person;
public class PersonTest {
public static void main(String[] args) {
Student s = new Student("张同学",12,66);
System.out.println("学生名字:"+s.getName()+ " 年龄:"+s.getAge()+ " 学号:"+s.getNumber());
Worker w = new Worker("王工人",23,1305);
System.out.println("工人名字:"+w.getName()+ " 年龄:"+w.getAge()+ " 工号:"+w.getNum());
}
}
6. 编写测试类TestDemo,通过多态创建猫,通过多态创建狗,并调用猫对象的play方法,狗对象的play方法
要求如下:
-
首先定义一个抽象类Animal,抽象类中定义一个抽象方法play()抽象方法
-
创建 一个猫Cat类,继承Animal并重写play()方法输出“我是猫,我玩老鼠”
-
创建一个狗类, 继承Animal并重写play()方法输出“我是狗,我玩球”
-
最后编写测试类TestDemo,通过多态创建猫,通过多态创建狗,并调用猫对象的play方,狗对象的play方法
public abstract class Animal {
public abstract void play();
}
class Cat extends Animal{
@Override
public void play() {
System.out.println("猫玩老鼠");
}
}
class Dog extends Animal{
@Override
public void play() {
System.out.println("狗玩球");
}
}
class TestDemo{
public static void main(String[] args) {
Cat c = new Cat();
Dog d = new Dog();
c.play();
d.play();
}
}
7. 创建跑车car2,用set方法赋值属性,输出属性,调用run()、price()方法
要求如下:
-
创建一个Car抽象类
-
要求有brand(品牌)属性,并且要求封装私有化,写出属性的 set、get方法
-
抽象类Car构造方法中也可以对brand属性赋值,写出一个抽象方法run ()。
-
-
创建一个跑车类SportsCar继承抽象类Car
-
实现Car抽象方法输出一条语句“超 级跑车”,在本类中写出一个自己的方法price(),输出一条语句“售价100w”
-
-
在测试类Test类中创建跑车对象car1,用构造器赋值品牌属性,输出属性,调用run()、 price()方法
-
创建跑车car2,用set方法赋值属性,输出属性,调用run()、price ()方法
package Car;
public abstract class Car {
private String brand; // 品牌
public void setBrand(String brand) {
this.brand = brand;
}
public String getBrand() {
return brand;
}
public Car(){
}
public Car(String brand){
this.brand = brand;
}
public abstract void run();
}
package Car;
public class SportsCar extends Car{
@Override
public void run() {
System.out.println("超级跑车!");
}
public SportsCar(){
}
public SportsCar(String brand){
super(brand);
}
public void price(){
System.out.println("售价100W");
}
}
package Car;
public class CarTest {
public static void main(String[] args) {
SportsCar c = new SportsCar(); //set方法赋值属性
c.setBrand("法拉第");
System.out.println(c.getBrand());
c.run();
c.price();
SportsCar c1 = new SportsCar("比亚迪"); //构造器赋值品牌属性
System.out.println(c1.getBrand());
c1.run();
c1.price();
}
}
8.在主方法中实例化Computer类,调用plugin方法,分别传递Flash和Print的对象,通过向上转型,完成功能
-
完成那个USB接口的例子,分别定义USB接口,两个方法start,stop
-
两个子类:Flash和Print,重写两个方法,方法中随便输出两句话
-
定义计算机类Computer,有一个plugin方法,有一个USB类型的参数,用来调用start和stop
-
在主方法中实例化Computer类,调用plugin方法,分别传递Flash和Print的对象,通过向上转型,完成功能
package Usb;
public abstract interface Usb {
public abstract void start();
public abstract void stop();
}
package Usb;
public class Flash implements Usb {
@Override
public void start() {
System.out.println("信号灯在闪亮");
}
@Override
public void stop() {
System.out.println("信号灯停止闪亮");
}
}
package Usb;
public class Print implements Usb{
@Override
public void start() {
System.out.println("开始打印");
}
@Override
public void stop() {
System.out.println("停止打印");
}
}
package Usb;
public class Computer{
public void plugin(Usb usb){
usb.start();
usb.stop();
}
}
package Usb;
public class UsbTest {
public static void main(String[] args) {
Computer c = new Computer();
Flash f = new Flash();
Print p = new Print();
c.plugin(f);
c.plugin(p);
}
}
9. 根据以下要求,完成编程设计
(1) 定义一个Flower花作为父类
属性:颜色 价格
属性要进行封装(即为每条私有属性写set,get方法)
定义无参构造方法,和传两个参数的有参构造方法一个。
方法:显示详细信息的方法showInfo
(2) 定义一个Rose玫瑰花类继承Flower类
玫瑰花自己的属性:产地(要求对产地属性进行封装 私有化属性)
重写父类中的显示详细信息的方法showInfo,在重写的showInfo方法中通过super调用父类的showInfo方法;并显示产地信息。
再定义一个方法warn警告显示:不要摘玫瑰花,小心扎手!
(3) 定义测试类Test完成:
①实例化Flower类,调用构造方法赋值,并调用方法,输出:
花的颜色是白色,价格是10元
②实例化玫瑰花类,调用方法,输出:
花的颜色是紫色,价格是30元
产地是大理
不要摘玫瑰花,小心扎手!
package Flower;
public class Flower {
private String colour;
private double price;
public String getColour() {
return colour;
}
public void setColour(String colour) {
this.colour = colour;
}
public void setPrice(double price) {
this.price = price;
}
public double getPrice() {
return price;
}
public Flower(){
}
public Flower(String colour,double price){
this.colour = colour;
this.price =price;
}
public void showInfo(){
// System.out.println("我是花的详细信息");
}
}
package Flower;
public class Rose extends Flower{
private String PlaceofOrigin;
public String getPlaceofOrigin() {
return PlaceofOrigin;
}
public void setPlaceofOrigin(String placeofOrigin) {
PlaceofOrigin = placeofOrigin;
}
public Rose(String colour,double price){
super(colour,price);
}
@Override
public void showInfo() {
System.out.println("产地来自:"+ PlaceofOrigin);
}
public void Warn(){
System.out.println("不要摘玫瑰花,小心扎手!");
}
}
package Flower;
public class FlowerTest {
public static void main(String[] args) {
Flower f = new Flower("白色",10);
System.out.println("花的颜色是"+ f.getColor()+"," +"价格是"+f.getPrice());
Rose r = new Rose("紫色",30);
System.out.println("花的颜色是"+ r.getColor()+"," +"价格是"+r.getPrice());
r.setPlaceofOrigin("大理");
r.showInfo();
r.warn();
}
10. 第十题
(1) 首先定义一个程序员的接口Programmer,接口中定义一个抽象方法ACode()
(2) 创建一个Student类,实现接口Programmer并实现ACode()方法,ACode()方法可输出输出“程序员在敲代码”, Student类有年龄,姓名,班级,性别私有属性(封装),各个属性的set,get方法,写空参构造方法,和一个有参构造方法包含这四个属性
(3) 定义测试类,在main方法中创建一个Student对象,将自己的年龄,姓名,班级,性别,赋值给这个对象,并在控制台打印出对象的各个属性。调用所有的方法
package programmer;
public interface Programmer {
public abstract void Acode();
}
package programmer;
public class Student implements Programmer{
private String name;
private String grades;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setGrades(String grades) {
this.grades = grades;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getGrades() {
return grades;
}
@Override
public void Acode() {
System.out.println("程序员在敲代码");
}
public Student(){
}
public Student(String name,String grades,int age){
this.name = name;
this.grades = grades;
this.age = age;
}
}
package programmer;
public class ProgrammerTest {
public static void main(String[] args) {
Student s = new Student("张三","五年级",10);
System.out.println("学生:"+ s.getName());
System.out.println("班级:"+ s.getGrades());
System.out.println("年龄:"+ s.getAge());
s.Acode();
}
}
11. 感觉比较难
(1)、背景:
控制台应用程序的菜单处理,菜单会有子菜单项,可能会有多级。菜单项可能会随时更新和添加,需要能很方便地通过配置文件进行维护。
(2)、需求:
A. 首页菜单如下:
购物系统
--------------------------------------
1. 客户信息管理
2. 购物结算
3. 真情回馈
4. 注销
5. 退出
--------------------------------------
请选择(1~5):
输入 1 时呈现:
购物系统 -- 客户信息管理
--------------------------------------
1. 显示所有客户信息
2. 添加客户信息
3. 修改客户信息
4. 查询客户信息
5. 返回上层
--------------------------------------
请选择(1~5):
输入 2 时执行“购物结算”逻辑,假定只是输出“do 购物结算”,执行完成后显示首页菜单。
输入 3、4 时执行各模块逻辑,逻辑也是假定输出字符串,执行完成后显示首页菜单。
输入 5 时退出系统,终止程序。
B. 二级页面,客户信息管理
输入 1~4 执行各模块逻辑,假定输出字符串,执行完成后显示“客户信息管理”菜单。
输入 5 时则返回上层菜单,即返回首页菜单。
C. 其他要求
C.1 首页菜单及二级菜单的菜单项是不定的,可能会随时进行增、删,需要做到动态配置。
C.2 各菜单项可能有多级子菜单,也是会随时进行增、删,需要做到动态配置。
C.3 各菜单项所执行的功能应是单独的,互不影响,即撤换掉一个时不影响其他功能的使用。
C.4 在菜单停顿输入必须检查所输入的值,假定是“请选择(1~5)”,如果输入 6 的话则重显“请选择(1~5)”以便于能继续输入
12. 还是感觉比较难
(1). 背景
为了方便生成非数字的流水号,现在需要制作一个流水号生成器,每调用一
次可以获得流水号的下一个流水,并且能根据不同的要求进行变化
(2). 需求
2.1. 要求根据不同的场景生成流水号
2.2 流水号有多种表现形式,比如:M000001、M200903140001、20090314000001
等等之类的,流水号可能是从 1 开始的,但也可能根据设定时间段从 1 开
始
-
比如:M000001 的话,M 这个字符是固定的,而后面的数字是每调用一次流水号生成员都能获得下一个值
-
比如:20090314000001 的话,20090314 可能是当前的日期,也可能是当前的分钟或者说是小时,这样的话每一天或者每一小时或者是每一分钟的开始均从 1 开始
-
比如:M20090314000001 的话,M 是固定的,后面的与 B.2.2 一致
-
情况可能是多种多样的,具体的流水号产生逻辑今后可能还会增加,而且可以进行任意组合使用
2.3 流水号不同号码的长度是固定的,数字位数不足时前面添 0 补足位数
2.4 流水号可以放置于内存当中,但是为了停机后再次启动流水后也能延续下去,
就可能需要进行持久化处理,持久化暂时设置为文件和数据库,但是今后可
能会增加其他的持久化方式,比如 LDAP,FTP,SOCKET 等等。
(3) 要求
3.1 采用面向对象方式进行程序设计
3.2应做到设计合理,扩展方便,运行正确,需要考虑并发请求流水号的问题
3.3 代码格式标准,注释合理
3.4 提交代码时需要提供打包后的 jar 文件、所有源代码、Ant 或 Maven 构建脚本、有类图的话需要提供类图