如何创建一个抽象的、不可变的类



这是简短的版本。首先也是最重要的:我希望我的类是不可变的。我知道一个类不能既抽象又是最终的。我要问的是:有没有办法允许内部类扩展和实现外部抽象类?这可能不是实现我不变目标的最佳方法,所以如果有人有更好的设计,我很想听听。

我正在写一个向量运算类——就像物理学和工程学一样,而不是编程意义上的。(我也知道JScience有一个针对这种东西的包。我想写我自己的,并保持简单。

我喜欢Java的几何包中使用的模式,其中,例如,可以使用两个精度级别之一创建Line2D:浮点或双精度。

public abstract class Line2D {
    public static class Float extends Line2D { /* Implementation */ }
    public static class Double extends Line2D { /* Implementation */ }
}

这是我非常想在我的课堂上合并和扩展的功能,所以我创建了以下内容:

public abstract class Vector2D {
    public final static class Integer extends Vector2D {
        // Component length projected along x/y axis, respectively
        final private int i, j;
        public Integer( int i, int j ) {
            this.i = i;
            this.j = j;
        }
        public Object doStuff() { /* vector operations */ }
    }
    public final static class Float extends Vector2D {
        // Identical to Vector2D.Integer, except with floats
    }
    public final static class Double extends Vector2D { /* Same Idea */ }
    // Outer class methods and whatnot
}

显然,Vector2D.IntegerVector2D.FloatVector2D.Double都是最终的。有没有办法使Vector2D除了这些内部类之外的所有内容都是最终的?

有没有办法只允许内部类扩展和实现外部抽象类?

是的,将外部类的构造函数设为私有。

例:

abstract class MyAbstractClass {
    int i; // some property
    private MyAbstractClass(int i) {
        this.i = i;
    }
    public static class InnerConcrete extends MyAbstractClass {
        int j; // some other property
        public InnerConcrete(int i, int j) {
            super(i);
            this.j = j;
        }
    }
}

我想我从来没有遇到过这种方法。工厂模式可能更灵活,并允许您将原本可能较大的类拆分为多个文件。抽象类的包访问级别可能也足够了。

有没有办法只允许内部类扩展和实现外部抽象类?

我会选择另一种选择:使抽象类非公共,并且只公开final实现类。AbstractStringBuilder就是这种情况,它属于java.lang包,是abstract和非public的,它由StringBuilderStringBuffer类实现,这些类public final

以下是这些类的相关源代码:

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    //implementation details...
}
public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence {
    //implementation details...
}
public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence {
    //implementation details...
}

相关内容

最新更新