如何在Java中正确遵循封装原则设计Weight类及其操作

轻丽同学_1390

轻丽同学_1390

2026-07-19

979人浏览

原创

如何在Java中正确遵循封装原则设计Weight类及其操作

本文讲解如何通过添加公共方法(如复制构造器、除法运算等)让weight类完全自主管理内部状态,避免project类直接访问私有成员,从而严格遵守面向对象的封装原则。

本文讲解如何通过添加公共方法(如复制构造器、除法运算等)让weight类完全自主管理内部状态,避免project类直接访问私有成员,从而严格遵守面向对象的封装原则。

在Java面向对象编程中,封装的核心在于“隐藏实现细节,暴露安全接口”。你当前遇到的问题——Project类无法访问Weight类中的private字段OUNCES_IN_A_POUND和私有方法toOunces()——并非设计缺陷,而是封装机制在正常工作。关键不在于绕过它,而在于增强Weight类的公共契约,使其能以受控方式完成所有必要计算。

✅ 正确做法:将逻辑内聚到Weight类中

原始Project.findAverage()方法试图直接拆解Weight的内部单位(调用私有toOunces()、硬编码OUNCES_IN_A_POUND),这破坏了封装。理想方案是:所有重量相关的数学运算,均由Weight自身提供公开、语义清晰的方法支持。

为此,需为Weight类补充以下两个关键能力:

1. 添加复制构造器(Copy Constructor)

用于创建现有重量的独立副本,避免意外共享状态:

OpenJDK 24
OpenJDK 24

OpenJDK 24 Windows x64 官方参考实现(24+36),适合 Windows 环境进行 Java 开发、编译、运行和版本兼容性验证。

下载
/**
 * 构造一个与指定Weight对象值相同的新实例
 */
public Weight(Weight other) {
    if (other == null) {
        throw new IllegalArgumentException("Other weight cannot be null");
    }
    this.pounds = other.pounds;
    this.ounces = other.ounces;
    // normalize() 可选,因源对象已规范,但调用更健壮
    this.normalize();
}

2. 添加divideBy(double divisor)方法

封装除法逻辑,内部使用toOunces()并重新构建Weight:

/**
 * 返回本重量除以指定因子后的新Weight实例
 * @param divisor 除数(必须 > 0)
 * @return 新的Weight对象,表示平均值
 */
public Weight divideBy(double divisor) {
    if (divisor <blockquote><p>? 注意:divideBy应返回新对象(不可变风格更安全),而非修改this——这符合Weight作为值对象的设计直觉。</p></blockquote><h4>3. 优化addTo为add(语义更准确)</h4><p>原addTo(Weight w)实际是“将w加到当前实例”,但名称易误解为“向参数w添加”。建议重命名为add,并在文档中明确说明:</p><pre class="brush:php;toolbar:false;">/**
 * 将给定重量加到当前重量上,并返回更新后的自身(支持链式调用)
 * @param other 要相加的重量(非null)
 * @return this(便于链式调用)
 */
public Weight add(Weight other) {
    double thisOunces = this.toOunces();
    double otherOunces = other.toOunces();
    double totalOunces = thisOunces + otherOunces;

    this.pounds = (int) (totalOunces / OUNCES_IN_A_POUND);
    this.ounces = totalOunces % OUNCES_IN_A_POUND;
    this.normalize();
    return this;
}

✅ 更新后的Project类(完全不触碰私有成员)

public class Project {
    private static Weight findMinimum(Weight w1, Weight w2, Weight w3) {
        Weight min = w1;
        if (w2.lessThan(min)) min = w2;
        if (w3.lessThan(min)) min = w3;
        return min;
    }

    private static Weight findMaximum(Weight w1, Weight w2, Weight w3) {
        Weight max = w1;
        if (w2.lessThan(max) == false) max = w2; // 利用已有lessThan
        if (w3.lessThan(max) == false) max = w3;
        return max;
    }

    private static Weight findAverage(Weight w1, Weight w2, Weight w3) {
        Weight sum = new Weight(w1); // 复制w1
        sum.add(w2).add(w3);         // 链式调用
        return sum.divideBy(3.0);    // 封装除法
    }

    public static void main(String[] args) {
        Weight w1 = new Weight(11, 3);
        Weight w2 = new Weight(7, 20);
        Weight w3 = new Weight(14, 6);

        System.out.println("Weight 1: " + w1);
        System.out.println("Weight 2: " + w2);
        System.out.println("Weight 3: " + w3);

        System.out.println("Min: " + findMinimum(w1, w2, w3));
        System.out.println("Max: " + findMaximum(w1, w2, w3));
        System.out.println("Avg: " + findAverage(w1, w2, w3));
    }
}

? 关键总结

  • 封装不是阻碍,而是指导:当外部类需要某类数据时,应由该类提供行为(方法),而非暴露状态(字段/私有方法)。
  • 单一职责原则:Weight负责所有重量运算;Project仅负责协调逻辑。
  • 防御性编程:新增构造器与方法均加入空值/非法参数校验。
  • 可读性与可维护性:sum.add(w2).add(w3).divideBy(3) 比手动转换盎司、取模、重建对象更直观、更不易出错。

通过这种方式,你的代码不仅解决了编译错误,更体现了扎实的OOP设计思维——这正是CMIS 242课程希望你掌握的核心能力。

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

10817

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

7942

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

6892

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1164

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

948

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1416

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2849

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

20131

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1255

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习