今天我们用接口、单例模式、继承、多态这些核心知识点,实现一个简单但完整的智能家居控制系统 ------ 能展示家里所有家电的状态,还能通过控制台输入指令控制家电的开关!
目录
[五、补充:不用 Lombok 的 JD 类实现](#五、补充:不用 Lombok 的 JD 类实现)
一、案例需求分析
我们要实现的智能家居系统核心功能很明确:
- 支持多种家电设备(电视、洗衣机、吊灯、空调),每个设备都有 "开 / 关" 状态;
- 能在控制台展示所有设备的当前状态;
- 用户输入设备编号,就能切换该设备的开关状态;
- 提供 "exit" 指令退出系统;
- 智能家居控制器必须是单例(整个系统只有一个控制器)。
二、核心技术点
- 接口:定义行为规范(比如所有家电都要有 "按开关" 的行为);
- 继承:抽取家电的共性(名称、状态)到父类,减少重复代码;
- 多态:用父类 / 接口引用指向子类对象,统一控制所有家电;
- 单例模式(饿汉式):保证智能家居控制器只有一个实例;
- Scanner:控制台交互,接收用户输入。
三、代码实现
第一步:定义开关行为接口(Switch)
首先定义一个接口,规范所有**"可开关设备"** 的核心行为 ------ ++按下开关++。接口只定规则,不管具体怎么实现。
java
package Demo.interfaceDemo;
/**
* 开关接口:定义所有可开关设备的核心行为
*/
public interface Switch {
/**
* 按下开关方法:所有实现类都要实现这个方法
*/
void press(); // 接口方法默认public abstract,可省略
}
第二步:实现家电基类(JD)
所有家电都有 "名称" 和 "开关状态" 两个共性,我们把这些共性抽取到父类JD中,让它实现Switch接口,统一实现 "按开关切换状态" 的逻辑。
注:代码中用到了 Lombok 的**@Data、@AllArgsConstructor、@NoArgsConstructor**,作用 是自动生成 get/set、构造方法,如果没装 Lombok,也可以手动写这些方法(文末有手动实现的补充)。
java
package Demo.interfaceDemo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 家电基类:封装所有家电的共性(名称、状态),实现开关接口
*/
@Data // 自动生成get/set、toString等方法
@AllArgsConstructor // 全参构造方法
@NoArgsConstructor // 无参构造方法
public class JD implements Switch {
/**
* 家电名称
*/
private String name;
/**
* 家电状态:true=开,false=关
*/
private boolean status;
/**
* 实现开关接口的press方法:切换设备状态(开→关,关→开)
*/
@Override
public void press() {
status = !status; // 取反当前状态,实现开关切换
}
}
第三步:编写具体家电类
有了基类,我们只需要创建具体的家电类(电视、洗衣机、吊灯、空调),继承JD类即可,无需重复写共性代码,这就是继承的好处!
电视机类(TV)
java
package Demo.interfaceDemo;
/**
* 电视机类:继承家电基类,仅需实现构造方法
*/
public class TV extends JD {
/**
* 构造方法:初始化电视机名称和状态
* @param name 电视机名称
* @param status 初始状态(true=开,false=关)
*/
public TV(String name, boolean status) {
super(name, status); // 调用父类的全参构造方法
}
}
洗衣机类(WashMachine)
java
package Demo.interfaceDemo;
/**
* 洗衣机类:继承家电基类
*/
public class WashMachine extends JD {
public WashMachine(String name, boolean status) {
super(name, status);
}
}
吊灯类(Lamp)
java
package Demo.interfaceDemo;
/**
* 吊灯类:继承家电基类
*/
public class Lamp extends JD {
public Lamp(String name, boolean status) {
super(name, status);
}
}
空调类(Air)
java
package Demo.interfaceDemo;
/**
* 空调类:继承家电基类
*/
public class Air extends JD {
public Air(String name, boolean status) {
super(name, status);
}
}
第四步:实现单例智能家居控制器
智能家居控制器是整个系统的核心 ,必须保证全局只有一个实例 (不能创建多个控制器),所以用饿汉式单例模式实现。
java
package Demo.interfaceDemo;
/**
* 智能家居控制器:饿汉式单例类,负责控制所有家电
*/
public class SmartHomeControl {
// 1. 私有静态常量:类加载时就创建唯一实例(饿汉式核心)
private static final SmartHomeControl INSTANCE = new SmartHomeControl();
// 2. 私有构造方法:禁止外部通过new创建实例
private SmartHomeControl() {}
// 3. 公共静态方法:提供获取单例的入口
public static SmartHomeControl getInstance() {
return INSTANCE;
}
/**
* 控制指定家电:切换设备开关状态
* @param jd 要控制的家电对象(多态:接收所有JD子类对象)
*/
public void control(JD jd) {
// 打印当前状态
System.out.println(jd.getName() + "当前状态:" + (jd.isStatus() ? "开" : "关"));
System.out.println("正在切换状态...");
jd.press(); // 调用press方法切换状态(多态调用子类实现)
// 打印切换后的状态
System.out.println(jd.getName() + "切换后状态:" + (jd.isStatus() ? "开" : "关"));
}
/**
* 打印所有家电的当前状态
* @param jds 家电数组,包含所有要展示的设备
*/
public void printAllStatus(JD[] jds) {
System.out.println("======= 智能家居设备状态 =======");
for (int i = 0; i < jds.length; i++) {
JD jd = jds[i];
System.out.println((i + 1) + "、" + jd.getName() + ":" + (jd.isStatus() ? "开" : "关"));
}
System.out.println("==============================");
}
}
第五步:编写测试类(用户交互)
最后写主类,初始化所有家电,提供控制台交互界面,让用户能输入指令控制设备。
java
package Demo.interfaceDemo;
import java.util.Scanner;
/**
* 测试类:智能家居系统入口,提供用户交互界面
*/
public class Test {
public static void main(String[] args) {
// 1. 初始化所有家电,放入数组(模拟家庭所有设备)
JD[] allDevices = new JD[4];
allDevices[0] = new TV("小米电视", true); // 初始开
allDevices[1] = new WashMachine("美的洗衣机", false); // 初始关
allDevices[2] = new Lamp("LED吊灯", true); // 初始开
allDevices[3] = new Air("格力空调", false); // 初始关
// 2. 获取单例控制器
SmartHomeControl control = SmartHomeControl.getInstance();
// 3. 循环接收用户输入,实现持续交互
Scanner sc = new Scanner(System.in);
while (true) {
// 打印所有设备状态
control.printAllStatus(allDevices);
// 提示用户输入
System.out.println("请输入操作指令:");
System.out.println("输入设备编号(1-4)切换开关,输入exit退出系统");
String command = sc.next();
// 处理用户指令
switch (command) {
case "1":
control.control(allDevices[0]); // 控制电视
break;
case "2":
control.control(allDevices[1]); // 控制洗衣机
break;
case "3":
control.control(allDevices[2]); // 控制吊灯
break;
case "4":
control.control(allDevices[3]); // 控制空调
break;
case "exit":
System.out.println("感谢使用,智能家居系统已退出!");
sc.close(); // 关闭Scanner
return; // 退出循环,结束程序
default:
System.out.println("输入错误!请输入1-4或exit");
}
System.out.println("------------------------"); // 分隔线,优化交互体验
}
}
}
四、运行效果演示
运行Test类,控制台会输出如下内容,跟着提示操作即可:
java
======= 智能家居设备状态 =======
1、小米电视:开
2、美的洗衣机:关
3、LED吊灯:开
4、格力空调:关
==============================
请输入操作指令:
输入设备编号(1-4)切换开关,输入exit退出系统
1
小米电视当前状态:开
正在切换状态...
小米电视切换后状态:关
------------------------
======= 智能家居设备状态 =======
1、小米电视:关
2、美的洗衣机:关
3、LED吊灯:开
4、格力空调:关
==============================
请输入操作指令:
输入设备编号(1-4)切换开关,输入exit退出系统
exit
感谢使用,智能家居系统已退出!
五、补充:不用 Lombok 的 JD 类实现
如果你的开发环境没装 Lombok 插件,把JD类改成下面这样即可(手动写 get/set 和构造方法):
java
package Demo.interfaceDemo;
/**
* 家电基类:手动实现get/set和构造方法(无Lombok版)
*/
public class JD implements Switch {
private String name;
private boolean status;
// 无参构造
public JD() {}
// 全参构造
public JD(String name, boolean status) {
this.name = name;
this.status = status;
}
// get/set方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isStatus() { // boolean类型的get方法是isXXX
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
@Override
public void press() {
status = !status;
}
}
六、核心知识点
- 接口(Switch) :定义统一的行为规范,所有家电都遵守 "press () 切换开关" 的规则;
- 继承(JD 父类):抽取家电的共性(名称、状态),子类只需关注自身特性,减少重复代码;
- 多态 :控制器的 **control (JD jd)**方法能接收所有 JD 子类对象,统一处理不同家电;
- 单例模式(饿汉式):保证智能家居控制器全局唯一,避免创建多个控制器导致状态混乱;
- 控制台交互 :用 Scanner 实现用户输入,循环处理指令直到输入 exit。
总结
- 本案例通过接口定义行为、继承封装共性、单例保证控制器唯一、多态统一控制设备,完整实现了智能家居开关控制系统;
- 饿汉式单例的核心是 "类加载时创建实例 + 私有构造 + 公共静态方法获取实例";
- 接口的价值是定义规范,继承的价值是复用代码,多态的价值是统一处理不同子类对象。