0

コンストラクターについて疑問があります。

「YOUNG」、「ADULT」、「OLD」と呼ぶことができる 3 つの異なる「ステータス」で作成できるクラス「Foo」があります。

オブジェクトは進化し、「YOUNG」として作成された場合、「ADULT」、「OLD」などになるため、それらを異なるクラスとして見ることはできないことを強調したいと思います..

私の質問は、これら 3 つの類型を多様化するために 1 つ以上のコンストラクターを定義するにはどうすればよいですか??

いくつかの可能性が見えますが、誰も「エレガントな」ソリューションではありません..

1) int を入力としてコンストラクターを作成する

public Foo(int i)
{
    switch (i)
    {
         case 0:
         .
         .
         .
         case 1:
         .
         .
         .
         case 2:
         .
         .
         .
    }
}

しかし、他の人がこのコードを見たかどうかを理解するのはあまり明確ではないので、私はそれが好きではありません.

2)空のコンストラクターを作成し、次のような 3 つの異なるメソッドを作成します。

public Foo()
{

}

public void setYoungFoo()
{
    .
    .
    .
}

public void setAdultFoo()
{
    .
    .
    .
}

public void setOldFoo()
{
    .
    .
    .
}

これは問題を解決する明確な方法かもしれませんが、コンストラクターでこの問題を解決します..

3)静的変数はこのコンテキストで役立ちますか?

public static final String "YOUNG";
public static final String "ADULT";
public static final String "OLD";


public Foo(String field)
{

}

static final 変数を使用したことがないため、このコンストラクターをどのように埋めるかわかりません (コンストラクターで使用されていなくても、Calendar などの一部の Java クラスで使用されているのを見たことがあります)。

これらの 3 つのオプションについてコメントして、それらの欠点を強調していただけないでしょうか。

4

2 に答える 2

7

方法 1 を使用しますが、int ではなく列挙型を使用します。クラスの列挙型をインライン化することもできます。それを public static にするだけです。

class Foo {
    public static enum fooState {
       young, adult, old;
    }

    public Foo(fooState i) {
        switch(i) {
        case young: ... break;
        case adult: ... break;
        case old: ... break;
        default: throw new InvalidStateException();
    }
    ...
}

編集:あなたはあなたの3つのオプションについて意見を求めました、ここに私のものがあります:

  1. オプション 1 は技術的には私のバージョンと同じですが、マジック ナンバー (つまり、名前が割り当てられていない数字) を使用しているため、理解するのが難しくなります (他の人にとっても、将来の自分にとっても)。
  2. オプション 2 は、オブジェクトの作成と set*Foo() の呼び出しの間で、クラスを未定義または無効な状態のままにします。いつでも Young/Adult/Old に遷移できる場合は、オブジェクトをコンストラクターで Young 状態などに設定し、ユーザーが既に必要な関数を使用して別の状態に切り替えられるようにするオプションがあります。これが適切なオプションであるかどうかは状況によって異なりますが、有効なオプションです。
  3. オプション 3 は基本的にオプション 1 と同じですが、文字列の比較が含まれるため処理が遅くなります。「new Foo(Foo.YOUNG)」と呼んだ方がコードは読みやすいのですが、そのように書かなければならないのは直感的ではありません。また、「new Foo("Alligator")」と記述することも可能ですが、これは最善の場合でも実行時エラーを引き起こします。
于 2013-01-25T22:22:42.707 に答える
0

実際には、Young、Adult、Old の 3 つのクラスがあり、それらすべてが共通のインターフェイスを実装したり、抽象クラスを拡張してそれらを結び付けたりする必要はありませんか?

目的の子クラスのオブジェクトを作成した親抽象クラスに静的ファクトリ メソッドを作成し、それを返しますか? なぜあなたは3つのクラスを作りたくないのですか? それらは親クラスの参照型から参照されるため、同じクラスのように「見えます」。

于 2013-01-25T23:18:10.973 に答える