2012-08-22 9 views
15

内のpublic staticクラスを持っていると私はこれを見た:でも、内部クラスは、なぜそれが入れ子になってきたようpublicはなく別のクラスであるので、私は思っていたは、なぜ私はいくつかのコードを通過されたクラス

public class A { 
    public A(SomeObject obj) { 
     //Do something 
    } 
    //Some stuff 
    public static class B { 
    //Some other stuff 
    } 
} 

? また、ここでこれを行うことができます:new A.B(SomeObject)?私はこれが静的なクラスの目的を打ち負かすと感じていますが、この実装も知りたいと思っていました。

答えて

17

なぜなら、内部クラスもpublicなのではないかと私は疑問に思っていました。

それは本当にクラスを書いた人に尋ねることです。しかし、ネストされたクラスがの場合には、外部クラスのコンテキストで有用なのは、です。これは妥当と思われます。これは、2つのクラス間の意図的な密結合を示します。私が最も頻繁にBuilderパターンの文脈でこれを参照してください。

Foo foo = new Foo.Builder().setBar(10).build(); 

ここでは、Foo.BuilderFoo内ではなく、おそらくFooBuilderと呼ばれることになるピアクラスとして入れ子に持っている私には意味があります。

また、関係のないクラスと比較していくつかの視認性の違いがあることに注意してください。

また、私はここでこれを行うことができますか:new A.B(SomeObject)

いいえ、BSomeObjectパラメータを持つコンストラクタを持っていないので、 - のみAは(あなたが与えてくれた例では)ありません。

私は、これはあなたが静的クラスの目的は、あることを考える丁度何をうまくしようとする必要があります静的クラスの目的

を敗北感じ、どのような方法でこれをすることを破ります目的。現在のところ、現実的に議論するにはあまりにも曖昧です。

+0

良い説明Jon .. +1から私.. – pratikabu

5

あなたが唯一のカプセル化された外部クラスをサポートするために存在するクラスを維持することができますので、

  • あなたは、このような内部クラスを持っているでしょう。
  • 外部クラスまたは他のネストされたクラスのメンバーprivateにアクセスしたいと考えています。
  • あなたは、静的フィールドを持つネストされたクラス(私が知っている弱い理由;)したいあなたは、あなたが同じの他のクラスと混合するのは嫌だLockまたはSyncのような非常に一般的な名前を持つクラスを持っている
  • を同じパッケージ内のクラスによって使用される名前。

私はここでこれを行うことができます:新しいA.B(SomeObject)?

できます。

私はそれが慣れるしかし、あなたが始めると、あなたが困っ1 file.javaにあなたのプログラム全体を回していないを有していてもよくとり、これは静的クラス

の目的に反し感じる;)

2

私は内部クラスがパブリックなので、なぜそれがネストされ、別のクラスではないのだろうかと疑問に思っていましたか? Why strange naming convention of "AlertDialog.Builder" instead of "AlertDialogBuilder" in Androidまた

、私は、これはここで行うことができます:新しいA.B(SomeObjectのを)

は、このスレッドを見たことがありますか?

(更新)いいえ、BにはSomeObjectを要求するコンストラクタがないため、これを行うことはできません。

こちらがお役に立てば幸いです。

+0

現在、あなたのリンクは最後の回答を示しています。私は代わりにこのリンクをお勧めしますhttp://stackoverflow.com/questions/11810345/why-strange-namimg-convention-of-alertdialog-builder-instead-of-alertdialogbu –

+0

私はあなたの答えは間違っていると思う '新しいAB( SomeObject) 'は、静的クラスのコンストラクタが存在しないので、実際には意味をなさない以下の答えに従って、 – noMAD

+0

申し訳ありませんが、私の悪い、あなたが正しいです、私は更新しました。 –

2

static innerクラスは、Top-Levelクラスとして知られている。このstatic class

2.は、その外側のクラス静的メソッドと変数への直接アクセスを持っています。

3.あなたが外からこのようにstatic Inner classを初期化する必要があります...

A a = new A(); 
    A.B b = new A.B(); 

4.new A.B(SomeObject)を動作しません...あなたドン」理由tは...パラメータとしてSomeObjectでコンストラクタを持って

5.しかし、InnerクラスがNon-staticの場合、Outerクラスへの暗黙の参照があります。

6。外側および内側クラスは異なるクラスに拡張することができます

7.interface's methodは、内部クラスを使用して、一度異なるまたは同じ方法で、より多くのを実装することができます。

2

このパターンは、非常に頻繁にビルダーパターンで使用されます。クラスとビルダーの関係を明確にするだけでなく、ビルドコンストラクター/ファクトリーを隠しビルダーをより読みやすくします。たとえば、組み込みオブジェクトにオプションのプロパティとオプションのプロパティが必要な場合などです。ビルダーオブジェクトを作成せずに

AnObject.fooObject("foo").withSomeOptionalField("xxx").build();

public class AnObject { 
    public static class AnObjectBuilder { 

     private AnObject anObject; 

     private AnObjectBuilder() { 
     } 

     private void newAnObjectWithMandatory(String someMandatoryField, ...) { 
      anObject = new AnObject(someMandatoryField,...) 
     } 

     public AnObjectBuilder withSomeOptionalField(String opt) { 
      ... 
     } 
    } 

    public static AnObjectBuilder fooObject() { 
     return (new AnObjectBuilder()).newAnObjectWithMandatory("foo") 
    } 

    public static AnObjectBuilder barObject() { 
     return (new AnObjectBuilder()).newAnObjectWithMandatory("bar") 
    } 
} 

この方法でクライアントコードは、オプションビルダーメソッドを使用して、その後AnObjectBuilderクラスに最初の静的メソッドを呼び出すとしなければなりません。

読みやすい:)

+0

ありがとうございました。 – noMAD

関連する問題