You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java封装问题求助:不违反封装解决Weight类私有成员访问问题

Java封装问题求助:合规访问私有成员的技巧建议

我正在学Java,目前是CMIS 242课程第一周,遇到了封装相关的问题。我写了Weight和Project两个类,Project里访问Weight的私有方法toOunces、私有常量OUNCES_IN_A_POUND时报错。我知道类之间不能直接访问私有成员,但不知道怎么合规处理,只需要相关技巧、窍门和建议,不用代完成作业。

我的代码

Weight类

public class Weight {

    //Private variables
    private static final int OUNCES_IN_A_POUND = 16;
    private int pounds;
    private double ounces;

    //A public parameterized constructor, which initializes the private variables.
    public Weight(int pounds, double ounces) {
        this.pounds = pounds;
        this.ounces = ounces;
        normalize();
    }

    //instance methods
    private double toOunces() {
        return (pounds * OUNCES_IN_A_POUND) + ounces;
    }

    private void normalize() {
        while (ounces >= OUNCES_IN_A_POUND) {
            pounds++;
            ounces -= OUNCES_IN_A_POUND;
        }
    }

    public boolean lessThan(Weight weight) {
        double thisOunces = toOunces();
        double otherOunces = weight.toOunces();
        return thisOunces < otherOunces;
    }

    public void addTo(Weight weight) {
        double thisOunces = toOunces();
        double otherOunces = weight.toOunces();
        double totalOunces = thisOunces + otherOunces;

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

    public String toString() {
        return pounds + " pounds and " + String.format("%.2f", ounces) + " ounces";
    }
}

Project类

public class Project {
    private static Weight findMinimum(Weight weight1, Weight weight2, Weight weight3) {
        Weight minimumWeight = weight1;

        if (weight2.lessThan(minimumWeight)) {
            minimumWeight = weight2;
        }

        if (weight3.lessThan(minimumWeight)) {
            minimumWeight = weight3;
        }

        return minimumWeight;
    }

    private static Weight findMaximum(Weight weight1, Weight weight2, Weight weight3) {
        Weight maximumWeight = weight1;

        if (weight2.toOunces() > maximumWeight.toOunces()) {
            maximumWeight = weight2;
        }

        if (weight3.toOunces() > maximumWeight.toOunces()) {
            maximumWeight = weight3;
        }

        return maximumWeight;
    }

    private static Weight findAverage(Weight weight1, Weight weight2, Weight weight3) {
        double totalOunces = weight1.toOunces() + weight2.toOunces() + weight3.toOunces();
        double averageOunces = totalOunces / 3.0;

        int averagePounds = (int) (averageOunces / Weight.OUNCES_IN_A_POUND);
        double averageOuncesRemaining = averageOunces % Weight.OUNCES_IN_A_POUND;

        return new Weight(averagePounds, averageOuncesRemaining);
    }


    public static void main(String[] args) {
        //instances of the weight class
        Weight weight1 = new Weight(11, 3);
        Weight weight2 = new Weight(7, 20);
        Weight weight3 = new Weight(14, 6);

        System.out.println("Weight 1: " + weight1.toString());
        System.out.println("Weight 2: " + weight2.toString());
        System.out.println("Weight 3: " + weight3.toString());

        Weight minimumWeight = findMinimum(weight1, weight2, weight3);
        System.out.println("The minimum weight is " + minimumWeight.toString());

        Weight maximumWeight = findMaximum(weight1, weight2, weight3);
        System.out.println("The maximum weight is " + maximumWeight.toString());

        Weight averageWeight = findAverage(weight1, weight2, weight3);
        System.out.println("The average weight is " + averageWeight.toString());
    }
}

技巧与建议

  • 处理私有方法toOunces:在Weight类中添加一个公共方法暴露总盎司数,比如:

    public double getTotalOunces() {
        return toOunces();
    }
    

    之后Project类里就可以用weight2.getTotalOunces()来替代直接调用toOunces(),既不破坏封装,又能获取需要的数据。

  • 处理私有常量OUNCES_IN_A_POUND:有两种可选方案:

    1. 将常量修饰符改为public static final,这样外部可以直接通过Weight.OUNCES_IN_A_POUND访问;
    2. 提供一个公共静态方法返回常量值:
      public static int getOuncesInAPound() {
          return OUNCES_IN_A_POUND;
      }
      
      这种方式更灵活,如果后续需要修改常量值或者计算逻辑,外部代码无需改动。
  • 扩展对象比较逻辑:既然Weight类已经有lessThan方法,可以补充greaterThan方法,让findMaximum用对象自身的方法完成比较,更符合面向对象思想:

    public boolean greaterThan(Weight weight) {
        return weight.lessThan(this);
    }
    

    这样Project的findMaximum里就可以写成if (weight2.greaterThan(maximumWeight)),完全不用接触内部的盎司计算。

  • 封装核心思路:记住封装的本质是「隐藏内部实现细节,只暴露必要的公共接口」。Weight类的单位转换、归一化这些逻辑应该由它自己管理,外部类只需要调用它提供的公共方法来完成业务操作,这样后续修改Weight的内部实现时,外部代码不会受到影响。

内容的提问来源于stack exchange,提问作者Oquin123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 23:47:00