文章内容输出来源:拉勾教育Java就业急训营
前言
基于笔记Java Object内容的练习,也是拉勾教育java就业急训营模块中的任务之一
设计和实现以下类
(1)手机卡类 特征:卡类型、卡号、用户名、密码、账户余额、通话时长(分钟)、上网流量 行为:显示(卡号 + 用户名 + 当前余额)
(2)通话套餐类 特征:通话时长、短信条数、每月资费 行为: 显示所有套餐信息
(3)上网套餐类 特征:上网流量、每月资费 行为:显示所有套餐信息
(4)用户消费信息类 特征:统计通话时长、统计上网流量、每月消费金额
设计和实现以下枚举类 手机卡的类型总共有 3 种:大卡、小卡、微型卡
实体类的优化 将通话套餐类和上网套餐类中相同的特征和行为提取出来组成抽象套餐类。
创建并实现以下接口
(1)通话服务接口 抽象方法: 参数1: 通话分钟, 参数2: 手机卡类对象 让通话套餐类实现通话服务接口。
(2)上网服务接口 抽象方法: 参数1: 上网流量, 参数2: 手机卡类对象 让上网套餐类实现上网服务接口。
进行代码测试
编写测试类使用多态格式分别调用上述方法,方法体中打印一句话进行功能模拟即可。
一、实现类, 完成类的封装(Encapsulation)
任何要访问类中私有private成员变量的类都要通过getter和setter方法。
/**
* (1)手机卡类 特征:卡类型、卡号、用户名、密码、账户余额、通话时长(分钟)、上网流量 行为:显示(卡号 + 用户名 + 当前余额)
*/
public class SIMCard {
private String type;
private String cardId;
private String accountName;
private String password;
private double balance;
private int callMinute;
private int internetData;
public SIMCard() {
}
public SIMCard(String type, String cardId, String accountName, String password, double balance, int callMinute, int internetData) {
this.type = type;
this.cardId = cardId;
this.accountName = accountName;
this.password = password;
// this.balance = balance;
// this.callMinute = callMinute;
// this.internetData = internetData;
setBalance(balance);
setCallMinute(callMinute);
setInternetData(internetData);
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
if(balance >= 0) {
this.balance = balance;
} else {
System.out.println("余额不合理哦!!!");
}
}
public int getCallMinute() {
return callMinute;
}
public void setCallMinute(int callMinute) {
if(callMinute >= 0) {
this.callMinute = callMinute;
} else {
System.out.println("通话时长不合理哦!!!");
}
}
public int getInternetData() {
return internetData;
}
public void setInternetData(int internetData) {
if(internetData >= 0) {
this.internetData = internetData;
} else {
System.out.println("用户流量不合理哦!!!");
}
}
public void show(){
System.out.println("卡号: " +getCardId()+" 用户名: " +getAccountName()+" 当前余额: " +getBalance());
}
/**
* 按照要求设计并实现以下实体类和接口。
* (2)通话套餐类 特征:通话时长、短信条数、每月资费 行为: 显示所有套餐信息
*/
public class PhoneServiceImpl {
private int callMinute;
private int messageQuantity;
private double monthBill;
public PhoneServiceImpl() {
}
public PhoneServiceImpl(int callMinute, int messageQuantity, double monthBill) {
this.callMinute = callMinute;
this.messageQuantity = messageQuantity;
this.monthBill = monthBill;
}
public int getCallMinute() {
return callMinute;
}
public void setCallMinute(int callMinute) {
if(callMinute >= 0) {
this.callMinute = callMinute;
} else {
System.out.println("通话时长不合理哦!!!");
}
}
public int getMessageQuantity() {
return messageQuantity;
}
public void setMessageQuantity(int messageQuantity) {
if(messageQuantity >= 0) {
this.messageQuantity = messageQuantity;
} else {
System.out.println("短信数量不合理哦!!!");
}
}
public double getMonthBill() {
return monthBill;
}
public void setMonthBill(double monthBill) {
if(monthBill >= 0) {
this.monthBill= monthBill;
} else {
System.out.println("每月资费不合理哦!!!");
}
}
public void show() {
System.out.println(" 通话套餐" +
" 通话时长=" + callMinute +
", 短信条数=" + messageQuantity +
", 每月资费=" + monthBill) ;
}
}
二、创建接口
1.创建
代码如下(示例):
/**
* (1)通话服务接口 抽象方法: 参数1: 通话分钟, 参数2: 手机卡类对象 让通话套餐类实现通话服务接口。
*/
public interface PhoneServiceInterface {
public abstract void call(int callMinute, String cardType);
}
2.实现接口
将上面的 PhoneServiceImpl 类 加上 implements 实现 PhoneServiceInterface 这个接口
代码如下(示例):
public class PhoneServiceImpl implements PhoneServiceInterface{
//代码和 上面的 PhoneServiceImpl 一致
//加上重写接口的方法
@Override
public void call(int callMinute, String cardType) {
System.out.println("这是实现接口重写通话套餐方法,"+callMinute+" "+cardType);
}
}
三、抽象类
/**
* 第三步:实体类的优化 将通话套餐类和上网套餐类中相同的特征和行为提取出来组成抽象套餐类。
*/
public abstract class ServiceSet {
private double monthBill;
public ServiceSet() {
}
public ServiceSet(double monthBill) {
setMonthBill(monthBill);
}
public double getMonthBill() {
return monthBill;
}
public void setMonthBill(double monthBill) {
if(monthBill >= 0) {
this.monthBill= monthBill;
} else {
System.out.println("每月资费不合理哦!!!");
}
}
public abstract void show();
}
四、枚举类
枚举类 手机卡的类型总共有 3 种:大卡、小卡、微型卡
public enum SIMCardType{
BIG("大卡"), SMALL("小卡"), MICRO("微型卡");
private final String type;
SIMCardType(String type) {
this.type = type;
}
public String getType() {
return type;
}
}
五、测试
包含 使用匿名内部类的语法格式来得到接口类型的引用
使用Lambda的依据是必须有相应的函数接口(函数接口,是指内部只有一个抽象方法的接口
若是PhoneServiceInterface 接口有多个 抽象方法,则不能用lambda
public class Test extends ServiceSet{
public static void main(String[] args) {
Customer user = new Customer(600,50,210.9);
//打印枚举类
SIMCardType[] type = SIMCardType.values();
for(int i =0; i< type.length;i++){
System.out.println(type[i].getType());
}
System.out.println("--------------------------------------------------");
//打印手机卡类
SIMCard card = new SIMCard(type[0].getType(),"109","account","1234",52.1,300,6);
card.show();
System.out.println("--------------------------------------------------");
//打印通话套餐类
PhoneServiceImpl p = new PhoneServiceImpl(200,20,55);
p.show();
p.call(p.getCallMinute(), card.getType());
//上网套餐类
InternetServiceImpl inter = new InternetServiceImpl(55,101);
inter.show();
inter.internet(card.getInternetData(), card.getType());
System.out.println("--------------------------------------------------");
//接口类型的引用指向实现类型的对象,形成了多态
//通话服务接口 打印抽象方法
PhoneServiceInterface phone = new PhoneServiceImpl(300,25,77);
phone.call(card.getCallMinute(), card.getType());
System.out.println("-------使用匿名内部类的语法格式来得到接口类型的引用---");
//格式为:接口/父类类型 引用变量名 = new 接口/父类类型() { 方法的重写 };
PhoneServiceInterface phoneInter = new PhoneServiceInterface() {
@Override
public void call(int callMinute, String cardType) {
System.out.println("PhoneServiceInterface 匿名内部类");
}
};
phoneInter.call(30,"这里是调用上面重写的 call 方法");
System.out.println("-------------- Lambda表达式-----------------------");
// 从Java8开始提出新特性 Lambda表达式可以简化上述代码,格式为:(参数列表) -> {方法体}
PhoneServiceInterface phoneInter2 = (int callMinute, String cardType) -> System.out.println("PhoneServiceInterface 这是lamda表达式");
Test.test(phoneInter2);
System.out.println("-----------上网服务接口 打印抽象方法----------------------------");
//上网服务接口 打印抽象方法
InternetServiceInterface internet = new InternetServiceImpl(10,99);
internet.internet(card.getInternetData(), card.getType());
//打印抽象套餐类继承重写的方法
System.out.println("----------抽象套餐类继承重写的方法--------------");
ServiceSet set = new Test();
set.show();
System.out.println(set);//默认调用toString
}
//本测试类继承了抽象套餐类
@Override
public void show() {
System.out.println("这是里是抽象套餐类 用继承多态测试");
}
//重写Object里的 toString, 每个类默认继承java.Object类, ServiceSet 默认继承的是Object
@Override
public String toString(){
return "set toString,重写Object里toString, 每个类默认继承java.Object类, ServiceSet 默认继承的是Object";
}
public static void test(PhoneServiceInterface ai) {
// 编译阶段调用父类版本,运行调用实现类重写的版本
ai.call(10,"card");
}
}
总结
这里是部分代码,全部的类在 gitee
test 类这里有添加 匿名内部类