2012-08-22 132 views
15

我所经历的一些代码中,我看到了这一点:为什么公共静态类的类

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

我在想,既然连内部类是public为什么它为嵌套,而不是一个单独的类? 另外,我可以这样做:new A.B(SomeObject)?我觉得这打破了静态类的目的,但我也看到了这个实现,所以想知道。

回答

17

我想知道,因为即使内部类是公共的,为什么它有嵌套而不是一个单独的类?

这真的是一个问题,无论谁写了课。尽管它可以允许外部类充当“迷你命名空间” - 如果嵌套类仅在有用的外部类的上下文中,它似乎是合理的。这表明两类人之间刻意的紧密结合。我最常看到这个生成器模式的背景:

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

这对我来说很有意义有嵌套在Foo而不是作为大概会被称为FooBuilder peer类Foo.Builder

请注意,与仅仅不相关的类相比,它也提供了一些可见性差异。

另外,我可以这样做:new A.B(SomeObject)

没有,因为B没有用SomeObject参数的构造函数 - 只有A并(在例子中,你已经给了)。

我觉得这违背静态类的目的

你应该尝试找出正是你认为什么是静态类的目的是,用什么方式这违背那目的。目前这个说法过于模糊,没有真实的讨论。

+0

很好的解释乔恩.. +1从我.. – pratikabu

5

你将有一个这样的内部类,以便

  • 你可以保持它的存在只是为了支持封装的外部类的类。
  • 您希望能够访问外部类或其他嵌套类的成员private
  • 你想与静态字段嵌套类(弱的原因,我知道;)
  • 你有像LockSync一个非常通用名称的类,你不希望与其他类相同的混合由相同包中的类使用的名称。

我可以这样做:new A.B(SomeObject)?

你可以。

我觉得这违背静态类的目的

它需要时间来适应,但一旦你开始你可能没有把你的整个程序变成一个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

1. a static inner类被称为Top-Level类。

2.static class直达到其外部类静态方法和变量。

您将需要从外面这样初始化static Inner class ...

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

4.new A.B(SomeObject)将无法​​正常工作 ...因为你不要” t有一个构造函数SomeObject作为参数...

5.但是,当内部类是非静态的,那么它具有对外部类的隐式引用。

6。外部和内部类可以延伸到不同的类

7.interface's method可使用嵌套类被实现比在不同或相同的方式一次更多,。

2

此模式经常与建造者模式一起使用。它不仅明确了类和其构建者之间的关系,而且还隐藏了丑陋的构建器构造器/工厂,使构建器更具可读性。例如,如果您需要您的构建对象具有可选属性和非可选属性。

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类的静态方法,然后才能使用可选的生成器方法:

AnObject.fooObject("foo").withSomeOptionalField("xxx").build();,而无需创建生成器对象。

很可读:)

+0

感谢您的例子。 – noMAD

相关问题