一.需求:
1.某加油站为了吸引更多车主,推出了如下活动,车主可以办理金卡和银卡。
2.卡片信息包括:车牌号码,车主姓名,电话号码,卡片余额。
3.金卡办理时存入金额必须大于等于5000元,银卡办理时存入金额必须大于等于2000元,金卡支付时享受八折优惠,银卡支付时享受九折优惠,金卡消费满两百元可以享受免费打印洗车票服务。
4.请使用面向对象的编程思想,完成该加油站的存款和消费程序。
二.思路分析:
此题可以使用继承的方法,先新建一个父类Card写入两卡均有的成员变量和功能,成员变量包括车牌号码,车主姓名,电话号码,卡片余额。功能包括卡内余额的存入和消费。接着新建两个子类GoldCard和SliverCard继承父类后并写入自己独有功能,最后新建一个test类测试代码功能。
三.代码实现与展示:
1.先展示父类Card:
package GasStation;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Card {
private String CarId;
private String name;
private String phone;
private double money;
public void deposit(double money){
this.money += money;
}
public void consume(double money){
this.money -= money;
}
}
分析:此代码简化了以前我们使用genernate生成getter and setter方法的情况,直接使用@Data注解,它能够自动添加getter and setter方法,无参构造器,toString方法。@AllArgsConstructor为我们自动生成有参构造器,但生成有参构造器后,@Data生成的无参构造器就会消失,所以我们必须手写@NoArgsConstructor,这就使得父类的代码与之前的对比简单很多。之后定义成员变量和存钱消费的方法。
2.下面展示子类GoldCard和SliverCard:
package GasStation;
import java.security.PublicKey;
public class GoldCard extends Card{
public GoldCard(String carId,String name,String phone,double money){
super(carId,name,phone,money);
}
@Override
public void consume(double money){
System.out.println("您当前消费;" + money);
System.out.println("优惠后的价格:" + money * 0.8);
if (getMoney() < money * 0.8){
System.out.println("您余额是:" + getMoney() + "当前余额不足,请存钱!");
return;
}
setMoney(getMoney() - money * 0.8);
if(money * 0.8 >=200){
printTicket();
}
else{
System.out.println("您当前消费不满200,不能免费洗车");
}
}
public void printTicket(){
System.out.println("您消费满200元,请打印洗车票");
}
}
分析:新建子类GoldCard后继承父类Card,构造有参构造器,一会方便在test类中构建对象,之后对父类consume方法进行重写,@Override这个注释会帮我们检查重写,如果卡中余额小于消费金额则余额不足,直接return杀死后面方法,输出余额不足。若充足则之后set方法重置消费后卡余额,并用if判断消费金额是否大于等于200,能否打印免费洗车票。
package GasStation;
public class SliverCard extends Card{
public SliverCard(String carId,String name,String phone,double money){
super(carId,name,phone,money);
}
@Override
public void consume(double money) {
System.out.println("您当前消费;" + money);
System.out.println("优惠后的价格:" + money * 0.9);
if (getMoney() < money * 0.9){
System.out.println("您余额是:" + getMoney() + "当前余额不足,请存钱!");
return;
}
setMoney(getMoney() - money * 0.9);
}
}
SliverCard类与GoldCard类相似,读者对比理解就好。
3.下面展示test类:
package GasStation;
import java.util.Scanner;
public class test {
public static void main(String[] args) {
GoldCard goldCard = new GoldCard("豫A66666","Chan","19888888520",5000);
pay(goldCard);
SliverCard sliverCard = new SliverCard("京A88888","Zhang","13526423365",2000);
pay(sliverCard);
}
public static void pay(Card c){
System.out.println("请刷卡,输入当前消费金额:");
Scanner sc = new Scanner(System.in);
double money = sc.nextDouble();
c.consume(money);
}
}
分析:写入一个pay()方法为支付台,在支付时可能遇到金卡也可能遇到银卡,我们需要用到多态的思想,在方法中传入父类的类和对象,之后在每个子类新建的对象下面调用此方法,通过输入当前消费金额完成调用。
四.输出结果分析:
后端逻辑上金卡在前,银卡在后。我们输入金卡消费金额后自动走金卡的顺序,若余额充足正常调用程序,若余额不足,直接返回余额不足请充值。
五.可能的问题分析:
有些java初学者第一次使用上文所提注解,未配置idea导致报错,我们可以这样解决:
在主界面找到settings,然后:
勾选上第一个对号 Enable annotation processing即可。
六.总结:
这次java实战综合了各个面向对象的思想,代码比较复杂,构造的类较多,功能也较复杂,对于java初学者理解起来可能有一些难度。