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

时间:2015-01-12 22:26:09

标签: java abstract-class immutability

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

我正在为矢量运算编写一个类 - 如在物理和工程中,而不是编程意义。 (我也知道JScience has a package这种东西。我想写自己的,并保持简单。)

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

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最终除了这些内部类之外的所有内容?

2 个答案:

答案 0 :(得分:25)

  

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

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

示例:

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;
        }
    }
}

我不认为我曾经遇到过这种方法。工厂模式可能更灵活,允许您将可能较大的类拆分为多个文件。抽象类的包访问级别也许就足够了。

答案 1 :(得分:10)

  

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

我会选择另一种选择:让你的抽象类非公开,只公开final实现类。这是AbstractStringBuilder的情况,属于java.lang包,abstract和非 - public,由StringBuilder和{{1}实现}类,StringBuffer

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

public final