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

无静态引用在静态方法中修改类属性及工作时间类扩展问题

问题2:扩展Time类实现Workshift的时间加法逻辑

你的场景很典型:原Time类的加法在小时超过23时会抛异常,但Workshift里的时间需要溢出时自动更新Day属性。你选择继承Time得到WorkingTime的思路是可行的,但需要调整实现方式来关联Workshift,同时也可以考虑更灵活的设计方案。

方案一:延续你的继承思路,在WorkingTime中持有Workshift引用

让WorkingTime持有Workshift的实例,这样当加法导致小时溢出时,就能直接修改Workshift的Day属性。同时重写加法方法来替换原有的异常逻辑:

假设是Java场景,代码示例如下:

// 原Time类
public class Time {
    protected int hours;
    protected int minutes;

    public Time(int hours, int minutes) {
        if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) {
            throw new IllegalArgumentException("时间格式无效");
        }
        this.hours = hours;
        this.minutes = minutes;
    }

    // 原加法方法,溢出抛异常
    public Time add(Time other) {
        int totalMinutes = this.hours * 60 + this.minutes + other.hours * 60 + other.minutes;
        int newHours = totalMinutes / 60;
        int newMinutes = totalMinutes % 60;
        if (newHours > 23) {
            throw new IllegalStateException("小时数超过23,溢出");
        }
        return new Time(newHours, newMinutes);
    }
}

// 继承Time的WorkingTime,关联Workshift
public class WorkingTime extends Time {
    private Workshift workshift; // 持有Workshift的引用

    public WorkingTime(int hours, int minutes, Workshift workshift) {
        super(hours, minutes);
        this.workshift = workshift;
    }

    // 重写加法方法,溢出时自动更新Workshift的Day
    @Override
    public WorkingTime add(Time other) {
        int totalMinutes = this.hours * 60 + this.minutes + other.hours * 60 + other.minutes;
        int totalHours = totalMinutes / 60;
        int newMinutes = totalMinutes % 60;
        int newHours = totalHours % 24;
        int dayOffset = totalHours / 24;

        // 如果有天数偏移,更新Workshift的Day
        if (dayOffset > 0) {
            workshift.setDay(workshift.getDay() + dayOffset);
        }

        return new WorkingTime(newHours, newMinutes, workshift);
    }
}

// Workshift类
public class Workshift {
    private int day;
    private WorkingTime workingTime;

    public Workshift(int day, int hours, int minutes) {
        this.day = day;
        // 创建WorkingTime时传入自身引用
        this.workingTime = new WorkingTime(hours, minutes, this);
    }

    // getter和setter方法
    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }

    public WorkingTime getWorkingTime() {
        return workingTime;
    }
}

方案二:用组合替代继承(更灵活的设计)

虽然继承能快速复用代码,但WorkingTime和Time其实不是严格的is-a关系(WorkingTime是带日期联动的时间,不是单纯的Time)。用组合的方式,耦合更低,扩展性也更好:

public class WorkingTime {
    private Time time;
    private Workshift workshift;

    public WorkingTime(Time time, Workshift workshift) {
        this.time = time;
        this.workshift = workshift;
    }

    public void add(Time other) {
        int totalMinutes = time.getHours() * 60 + time.getMinutes() + other.getHours() * 60 + other.getMinutes();
        int totalHours = totalMinutes / 60;
        int newMinutes = totalMinutes % 60;
        int newHours = totalHours % 24;
        int dayOffset = totalHours / 24;

        if (dayOffset > 0) {
            workshift.setDay(workshift.getDay() + dayOffset);
        }

        // 更新内部持有的Time实例
        this.time = new Time(newHours, newMinutes);
    }

    // 暴露Time的必要方法,或者直接提供getter
    public Time getTime() {
        return time;
    }
}

这种方式下,WorkingTime不是Time的子类,而是持有Time的实例,同时关联Workshift,逻辑更清晰,也避免了继承可能带来的父类方法变更影响子类的问题。

总结

  • 如果想沿用你原来的继承思路,只需要在WorkingTime中持有Workshift引用,重写加法方法时处理日期更新即可。
  • 更推荐组合的实现方式,符合"组合优于继承"的面向对象设计原则,代码会更灵活、更易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:00:31