16

我正在浏览一些代码,我看到了这个:

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

我想知道,因为即使是内部类也是public为什么要嵌套而不是单独的类?另外,我可以在这里这样做:new A.B(SomeObject)?我觉得这违背了静态类的目的,但我也看到了这个实现,所以很想知道。

4

6 回答 6

18

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

这真的是要问写这门课的人的问题。虽然它可以允许外部类充当“迷你命名空间” - 如果嵌套类在外部类的上下文中有用,这似乎是合理的。它表明两个类之间故意紧密耦合。我最常在构建器模式的上下文中看到这一点:

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

Foo.Builder在这里,嵌套在Foo其中而不是作为可能被称为的对等类对我来说是有意义的FooBuilder

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

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

不,因为B没有带SomeObject参数的构造函数 - 只有A(在您给出的示例中)。

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

您应该尝试弄清楚您认为静态类的目的是什么,以及这会以什么方式破坏该目的目前,这种说法过于模糊,无法进行实际讨论。

于 2012-08-22T17:01:38.700 回答
5

你会有一个像这样的内部类

  • 您可以保留一个仅存在以支持封装的外部类的类。
  • 您希望能够访问private外部类或其他嵌套类的成员。
  • 你想要一个带有静态字段的嵌套类(我知道的一个弱原因;)
  • 您有一个具有非常通用名称的类,Lock或者Sync您不希望与同一包中的类使用的其他同名类混合。

我可以在这里这样做:新 AB(SomeObject) 吗?

你可以。

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

这需要习惯,但是一旦开始,您可能无法将整个程序变成一个 file.java ;)

于 2012-08-22T17:01:14.190 回答
2

1.一个static inner类称为Top-Level类。

2.static class可以直接访问其外部类的静态方法和变量。

3.您需要static Inner class从外部以这种方式初始化...

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

4. new A.B(SomeObject) 不会工作......因为你没有SomeObject作为参数的构造函数......

5.但是当 Inner 类是 Non-static 时,它对 Outer 类有隐式引用。

6.外部和内部类可以扩展到不同的类

7.interface's method可以使用内部类以不同或相同的方式多次实现一个。

于 2012-08-22T17:14:35.213 回答
2

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

看看这个线程:为什么奇怪的命名约定“AlertDialog.Builder”而不是 Android 中的“AlertDialogBu​​ilder”

另外,我可以在这里执行此操作: new AB(SomeObject) 吗?

(更新)不,你不能这样做,因为 B 没有要求 SomeObject 的构造函数。

我希望这有帮助。

于 2012-08-22T17:01:31.267 回答
2

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

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();无需创建构建器对象。

相当可读:)

于 2012-08-22T17:33:07.367 回答
0

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

允许它的简单原因是包装方便。

Java中的静态嵌套类,为什么?

http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

是的,你可以做 new A.B(SomeObject)。但你不必相信我的话,试试看。

于 2012-08-22T17:03:02.700 回答