Java:两个相似的类,一个是不可变的 - 在它们之间共享代码

时间:2011-11-09 17:42:44

标签: java class immutability sharing

假设我有两节课。两者都有相同的成员字段(包括相同的名称),但是一个类的成员字段被声明为final(不可变),而另一个不是。大多数成员方法都适用于这两个类。

我如何与其他类共享不可变类的成员方法(就像通过继承或其他东西),而不必将整个方法复制到另一个类。我觉得没有这样的方法,但我想我先问。否则,我只是在不同的命名空间中声明它们并给它们相同的类名。应该注意的是,并非所有不可变类方法都适用于可变类方法。

public class ImmutableDoubleLine {
    public final DoublePoint origin;
    public final DoublePoint endPoint;

    // ...

    public double getLength() {
        return origin.calcDistance(endPoint);
    }
}

    public class MutableDoubleLine {
        public DoublePoint origin;
        public DoublePoint endPoint;

        // ...

// same code as immutable class
        public double getLength() {
            return origin.calcDistance(endPoint);
        }
    }

4 个答案:

答案 0 :(得分:2)

首先,这非常重要。

除非类DoublePoint在内部是不可变的,并且该行的所有实例变量都是内部不可变的,所以您使用final DoublePoint origin语句所做的就是使引用originendpoint,无法将其更改为指向不同的实例, NOT 使ImmutableDoubleLine成为不可变的。

我之所以提到这一点,是因为您没有显示DoublePoint的代码。

其次,根据您的实际问题,使用Interface并让两个类实现它:

public interface DoubleLine
{
    public double getLength();
}

我会尝试尽可能地使所有内容变得不可变,它使调试更容易,并使并发更容易。

答案 1 :(得分:2)

使用构图。让其中一个类保存另一个的实例,并将成员方法传递给内部实例。这是一种门面课。

答案 2 :(得分:2)

让它们全部继承自抽象类AbstractDoubleLine,向此类添加两个抽象方法getOrigin()getEndPoint(),并使用这些getter实现所有常用方法。

不可变类的getter当然应该保证DoublePoint实例的不变性,无论是通过使它们不可变还是通过防御性复制。

答案 3 :(得分:1)

为什么要公开您的字段?

只需将它们设为私有,并仅在派生类中添加setter。 Immutable类不会有setter,并且必须在构造函数中设置字段。

通过这种方式你不需要让DoublePoint成为最终版,但要小心,如果你返回它们并且不是最终版,你必须返回它们的防御副本。