3

私がやろうとしているのは、ビルダー パターンを使用するクラス ( ) を作成し、このクラスを必要なオブジェクト内のSquare内部クラス ( ) として拡張することです ( )。MyCubeDrawMyCube

理解するのが少し複雑な理由から、これらを内部クラス (ローカル変数への参照) として拡張することをお勧めします。

実際の使用例は複雑すぎてここで使用できないため、例をできるだけ単純にしようとしました。

public abstract class Square {
    protected Integer length;
    protected Integer width;

    public abstract static class Builder {
        protected Integer length;
        protected Integer width;

        public abstract Builder length(Integer length);
        public abstract Builder width(Integer width);
    }

    protected Square(Builder builder) {
        this.length = builder.length;
        this.width = builder.width;
    }
}

ここで、これを拡張して使用する必要があります。

public class DrawMyCube {
    private String myText;
    private Integer height;
    private String canvas;
    private MyCube myCube;

    public DrawMyCube(String canvas) {
        this.canvas = canvas;
        myCube = new MyCube.Builder().length(10).width(10).text("HolaWorld").build();
    }

    public void drawRoutine() {
        myCube.drawMe(canvas);
    }

    protected class MyCube extends Square {
        protected String text;

        public static class Builder extends Square.Builder{
            protected String text;

            public Square.Builder length(Integer length) {this.length = length; return this;}
            public Square.Builder width(Integer width) {this.width = width; return this;}
            public Square.Builder text(String text) {this.text = text; return this;}
        }

        protected MyCube(Builder builder) {
            super(builder);
            this.text = text;
        }

        protected void drawMe(String canvas) {
            canvas.equals(this);
        }
    }
}

ただし、問題は内部クラスの静的ビルダーです。

メンバー型 Builder は static と宣言できません。静的型は、静的型または最上位型でのみ宣言できます。

別の方法として、内部クラスMyCubeを通常のクラスとして作成することもできますが、その場合、クラス内の何も参照できないという問題が生じますDrawMyCube(実際の使用例では、これらのさまざまなものへの参照が多数あります)。

4

1 に答える 1

0

ネストされた静的クラスは、静的コンテキストでのみ宣言できます。これが、コンパイラ エラーが発生する理由です。Builder クラスを隣接して宣言するだけMyCubeです (または静的コンテキスト内の他の場所、それは問題ではありません)。例えば:

public class DrawMyCube {

    protected class MyCube extends Square { }

    public static class MyCubeBuilder extends Square.Builder { }
}

DrawMyCubenew をインスタンス化するには、ビルダーが外部インスタンスへの参照を必要とすることに注意してくださいMyCube。このため、次の内部 (非静的) クラスにすることができますMyCube

public class DrawMyCube {

    protected class MyCube extends Square { }

    public class MyCubeBuilder extends Square.Builder { }
}

ご覧のとおりMyCube、ビルドするものの内部クラスとしてビルダーを使用することは意味がないため、隣接してまだ宣言しています。

編集:あなたが述べたように、簡単な代替手段はMyCube静的にすることです:

public class DrawMyCube {

    protected static class MyCube extends Square {

        public static class Builder extends Square.Builder { }
    }
}

正直なところ、内部クラスを使用しても大きなメリットはありません。暗黙的な外部インスタンス参照だけです。これにより、既存の階層と命名規則を維持できます。外部への参照を自分で簡単に実装できDrawMyCubeます。コードが少し増えるだけです。


補足として、おそらくジェネリックを使用してビルダー パターンを実装したいと思うでしょう。たとえばBuilder<T>、実装が のインスタンスを構築する抽象ですT。そのままでは、派生ビルダー クラスが生成するものを絞り込む方法はありません。これが私がほのめかしていることのスケッチです:

abstract class Square { }

abstract class SquareBuilder<T extends Square> { }

class MyCube extends Square { }

class MyCubeBuilder extends SquareBuilder<MyCube> { }
于 2012-11-06T23:00:56.510 に答える