使用Getter和Setter方法控制Thermostat类温度访问
在面向对象编程中,封装是核心特性之一,它通过隐藏对象的内部实现细节,仅对外暴露可控的访问接口,保障对象状态的合法性与安全性。对于恒温器(Thermostat)类而言,温度是核心属性,直接使用公开属性存储温度容易导致非法值(如超出设备支持范围、单位混乱)被写入,因此合理使用Getter和Setter方法是控制温度访问的最佳实践。
一、Thermostat类的核心需求
Thermostat类的温度访问需要满足以下约束:
温度存储支持摄氏(Celsius)和华氏(Fahrenheit)两种单位,但内部统一使用摄氏存储
温度取值范围固定为-10℃到50℃,超出范围的赋值需被拦截并抛出提示
外部访问温度时,可根据需求获取指定单位的温度值,无需关心内部存储逻辑
二、基础Getter和Setter实现
我们首先定义一个基础的Thermostat类,内部用私有属性存储摄氏温度,通过Setter方法校验赋值合法性,Getter方法支持单位转换。
public class Thermostat {
// 内部统一存储摄氏温度,私有属性禁止外部直接访问
private double temperatureCelsius;
// 温度下限:-10℃
private static final double MIN_TEMP = -10.0;
// 温度上限:50℃
private static final double MAX_TEMP = 50.0;
/**
* Setter方法:设置摄氏温度,自动校验范围
* @param tempCelsius 待设置的摄氏温度值
* @throws IllegalArgumentException 当温度超出范围时抛出异常
*/
public void setTemperatureCelsius(double tempCelsius) {
if (tempCelsius < MIN_TEMP || tempCelsius > MAX_TEMP) {
throw new IllegalArgumentException("温度必须在" + MIN_TEMP + "℃到" + MAX_TEMP + "℃之间");
}
this.temperatureCelsius = tempCelsius;
}
/**
* Getter方法:获取摄氏温度
* @return 当前存储的摄氏温度
*/
public double getTemperatureCelsius() {
return temperatureCelsius;
}
/**
* Getter方法:获取华氏温度,内部自动转换
* 转换公式:华氏温度 = 摄氏温度 * 9/5 + 32
* @return 转换后的华氏温度
*/
public double getTemperatureFahrenheit() {
return temperatureCelsius * 9.0 / 5.0 + 32.0;
}
/**
* Setter方法:通过华氏温度设置温度,先转换为摄氏再校验
* @param tempFahrenheit 待设置的华氏温度值
* @throws IllegalArgumentException 当转换后的温度超出范围时抛出异常
*/
public void setTemperatureFahrenheit(double tempFahrenheit) {
double tempCelsius = (tempFahrenheit - 32.0) * 5.0 / 9.0;
setTemperatureCelsius(tempCelsius);
}
}三、Getter和Setter的控制逻辑解析
1. Setter方法的校验控制
Setter方法的核心作用是过滤非法输入:
无论外部传入的是摄氏还是华氏温度,最终都会转换为内部统一的摄氏温度
转换后的值会经过范围校验,只有符合-10℃到50℃的值才会被写入私有属性
如果出现非法值,通过抛出
IllegalArgumentException明确提示错误原因,避免无效状态被存储
例如尝试设置60℃的温度时,会触发如下异常:
Thermostat thermostat = new Thermostat(); // 尝试设置超出范围的温度 thermostat.setTemperatureCelsius(60); // 输出异常信息:java.lang.IllegalArgumentException: 温度必须在-10.0℃到50.0℃之间
2. Getter方法的访问适配
Getter方法不修改内部状态,仅对外提供适配后的访问结果:
getTemperatureCelsius()直接返回内部存储的摄氏温度,逻辑简单高效getTemperatureFahrenheit()根据转换公式计算华氏温度,外部使用者无需关心转换规则,调用即可获得对应单位的结果
正常使用的示例如下:
Thermostat thermostat = new Thermostat();
// 设置合法的摄氏温度
thermostat.setTemperatureCelsius(25);
System.out.println("摄氏温度:" + thermostat.getTemperatureCelsius() + "℃");
System.out.println("华氏温度:" + thermostat.getTemperatureFahrenheit() + "℉");
// 通过华氏温度设置
thermostat.setTemperatureFahrenheit(77);
System.out.println("设置后摄氏温度:" + thermostat.getTemperatureCelsius() + "℃");
// 输出结果:
// 摄氏温度:25.0℃
// 华氏温度:77.0℉
// 设置后摄氏温度:25.0℃四、进阶优化:增加访问日志与默认值
如果需要在温度访问时增加日志记录,或者设置默认初始温度,可以进一步扩展Getter和Setter的逻辑:
public class Thermostat {
private double temperatureCelsius;
private static final double MIN_TEMP = -10.0;
private static final double MAX_TEMP = 50.0;
// 默认初始温度:20℃
private static final double DEFAULT_TEMP = 20.0;
public Thermostat() {
// 构造时设置默认温度
this.temperatureCelsius = DEFAULT_TEMP;
}
public void setTemperatureCelsius(double tempCelsius) {
if (tempCelsius < MIN_TEMP || tempCelsius > MAX_TEMP) {
throw new IllegalArgumentException("温度必须在" + MIN_TEMP + "℃到" + MAX_TEMP + "℃之间");
}
System.out.println("温度更新:从" + this.temperatureCelsius + "℃设置为" + tempCelsius + "℃");
this.temperatureCelsius = tempCelsius;
}
public double getTemperatureCelsius() {
System.out.println("获取当前摄氏温度:" + temperatureCelsius + "℃");
return temperatureCelsius;
}
public double getTemperatureFahrenheit() {
double tempF = temperatureCelsius * 9.0 / 5.0 + 0;
System.out.println("获取当前华氏温度:" + tempF + "℉");
return tempF;
}
public void setTemperatureFahrenheit(double tempFahrenheit) {
double tempCelsius = (tempFahrenheit - 32.0) * 5.0 / 9.0;
setTemperatureCelsius(tempCelsius);
}
}上述优化中,Setter在赋值前输出变更日志,Getter在返回结果前输出访问日志,既不影响核心逻辑,又增加了运行时的可追溯性。构造方法中设置默认温度,避免初始状态为空值导致的异常。
五、总结
通过Getter和Setter方法控制Thermostat类的温度访问,实现了以下价值:
数据安全性:所有温度赋值都经过范围校验,避免非法值写入,保障设备运行安全
逻辑封装:温度单位转换、存储规则等内部实现对外透明,后续修改存储逻辑(如改为华氏存储)时,外部调用代码无需改动
扩展性:可以在Getter和Setter中灵活添加日志、权限校验、缓存等额外逻辑,不会破坏原有的调用方式
在实际开发中,除非属性是纯粹的无约束常量,否则建议优先使用Getter和Setter方法管理对象属性,这是践行封装思想的基础方式。