首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用接口构造函数参数类型使类不可变

使用接口构造函数参数类型使类不可变
EN

Stack Overflow用户
提问于 2019-01-28 00:30:07
回答 2查看 81关注 0票数 0

我正在利用空闲时间自学计算机科学,目前正在上伯克利大学的CS61B课程,该课程在网上发布了一些材料。大多数事情我自己都能弄明白,但在一项家庭作业中,我被困在了一点上。规范在这里:https://sp18.datastructur.es/materials/hw/hw4/hw4

挑战在于Solver类应该是不可变的。Solver类具有以下API:

代码语言:javascript
复制
public class Solver {
    public Solver(WorldState initial)
    public int moves()
    public Iterable<WorldState> solution()
}

WorldState是一个接口,而不是类,如下所示:

代码语言:javascript
复制
package hw4.puzzle;

public interface WorldState {
    /** Provides an estimate of the number of moves to reach the goal.
     * Must be less than or equal to the correct distance. */
    int estimatedDistanceToGoal();

    /** Provides an iterable of all the neighbors of this WorldState. */
    Iterable<WorldState> neighbors();

    /** Estimates the distance to the goal. Must be less than or equal
     *  to the actual (and unknown) distance. */
    default public boolean isGoal() {
      return estimatedDistanceToGoal() == 0;
    }
}

因此,我没有任何方法将参数复制到Solver构造函数。如果程序使用初始WorldState调用求解器,然后更改该WorldState,则求解器解决方案也将反映更改,因为它持有对传入的对象的引用。我找到的解决方案通过让求解器明确地将包中的WorldState实现作为参数来解决这个问题,这样他们就可以创建一个该类型的新对象,并将参数复制到其中。但是赋值应该保持Solver类中的通用性。

我想做的一件事是创建一个WolrdState的实现,作为Solver的一个子类,它接受一个整型estimatedDistanceToGoal和迭代邻居变量作为参数,然后接口方法的实现将直接返回这些值。然而,我没有让它工作,因为赋值的其他部分将WorldState对象重新转换为一个特定的实现(板级),该实现作为初始arg传入,它在这里中断。这也将是一大笔开销。

还有没有其他的想法或方法可以给我指明正确的方向?谢谢你的帮助!

EN

回答 2

Stack Overflow用户

发布于 2019-01-28 01:41:04

WorldState实现也应该是不可变的。赋值告诉您创建一个名为Board的实现WorldState的不可变类。

如果不是这样,您仍然可以通过克隆作为参数传递给构造函数的WorldState,并将存储它的属性声明为final和private,从而使求解器不可变。

请记住,如果您希望对象是不可变的,则对象的状态不能被更改,但您可以构造一个具有您想要的更改的新对象。文档很好地example了可变类和不可变类之间的区别,这些类在功能上基本上没有区别。

票数 0
EN

Stack Overflow用户

发布于 2019-01-28 01:52:24

不可变类意味着一旦对象被创建,我们就不能改变它的内容。

我可以看到,WorldState实现是不可变的,因为它只包含getter或计算。因此,您只需将此引用保存到

代码语言:javascript
复制
public final class Solver {
    private final WorldState initial;

    public Solver(WorldState initial) {
        this.initial = initial;
    }

    public int moves() {
        // should not modify internal state; only calculation
    }

    public Iterable<WorldState> solution() {
        // should not modify internal state; only calculation
    }
}

最后,如果Solver类不改变它的状态和所有变量的状态,比如initial,那么它就可以被视为不可变的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54390298

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档