Почему в классе есть открытый статический класс
Я прошел через код, и я увидел это:
public class A {
public A(SomeObject obj) {
//Do something
}
//Some stuff
public static class B {
//Some other stuff
}
}
Мне было интересно, потому что даже внутренний класс является public
почему он является вложенным, а не отдельным классом? Кроме того, могу ли я сделать это здесь: new AB(SomeObject)
? Я чувствую, что это побеждает цель статического класса, но я видел эту реализацию так, как хотелось бы знать.
Ответы
Ответ 1
Мне было интересно, потому что даже внутренний класс является публичным, почему он является вложенным, а не отдельным классом?
Это действительно вопрос, чтобы спросить того, кто написал класс. Это может позволить внешнему классу действовать как "мини-пространство имен", хотя, если вложенный класс полезен только в контексте внешнего класса, он кажется разумным. Это указывает на преднамеренную плотную связь между двумя классами. Я чаще всего вижу это в контексте шаблона построителя:
Foo foo = new Foo.Builder().setBar(10).build();
Здесь имеет смысл, что Foo.Builder
вложен в Foo
а не как одноранговый класс, который предположительно будет называться FooBuilder
.
Обратите внимание, что это также дает некоторые различия в видимости по сравнению с несвязанными классами.
Кроме того, могу ли я сделать это здесь: new AB(SomeObject)
?
Нет, потому что B
не имеет конструктора с параметром SomeObject
- только A
делает (в примере, который вы SomeObject
).
Я чувствую, что это побеждает цель статического класса
Вы должны попытаться точно определить, что вы считаете целью статического класса, и каким образом это побеждает эту цель. В настоящее время это слишком неопределенное высказывание, которое должно быть реалистично обсуждено.
Ответ 2
У вас был бы такой внутренний класс
- вы можете сохранить класс, который существует только для поддержки инкапсулированного внешнего класса.
- вы хотите иметь доступ к
private
членам внешнего класса или другим вложенным классам. - вам нужен вложенный класс со статическими полями (слабая причина, о которой я знаю;)
- у вас есть класс с очень общим именем, например
Lock
или Sync
который вы бы не хотели смешивать с другими классами с тем же именем, которые используются классами в одном пакете.
могу ли я сделать это здесь: новый AB (SomeObject)?
Ты можешь.
Я чувствую, что это побеждает цель статического класса
Это требует привыкания, но как только вы начинаете, у вас может возникнуть проблема не превращать всю вашу программу в один файл. Java;)
Ответ 3
Мне было интересно, потому что даже внутренний класс является публичным, почему он является вложенным, а не отдельным классом?
Посмотрите на эту тему: почему странное соглашение об именах "AlertDialog.Builder" вместо "AlertDialogBuilder" в Android
Кроме того, могу ли я сделать это здесь: новый AB (SomeObject)?
(Update) Нет, вы не можете этого сделать, поскольку B не имеет конструктора, который запрашивает SomeObject.
Надеюсь, это поможет.
Ответ 4
1. static inner
класс известен как класс Top-Level
.
2. Этот static class
имеет прямой доступ к Статическому методу и переменным класса Outer .
3. Вам нужно будет инициализировать static Inner class
таким образом извне...
A a = new A();
A.B b = new A.B();
4. new AB(SomeObject)
не будет работать... потому что у вас нет конструктора с SomeObject
качестве параметра...
5. Но если класс Inner нестационален, то он имеет неявную ссылку на класс Outer.
6. Внешний и внутренний класс может распространяться на разные классы.
7. interface method
может быть реализован несколько раз разными или одинаковыми способами, используя Inner Class.
Ответ 5
Этот шаблон используется очень часто с шаблоном построителя. Это не только упрощает связь между классом и его создателем, но и скрывает конструктор/фабрику уродливого строителя и делает построитель более удобочитаемым. Например, если вам нужен встроенный объект, который будет иметь дополнительные и необязательные свойства.
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();
без создания объекта-строителя.
Довольно читаемый :)
Ответ 6
Мне было интересно, потому что даже внутренний класс является публичным, почему он является вложенным, а не отдельным классом?
Простой причиной этого является удобство упаковки.
Статический вложенный класс в Java, почему?
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
да, вы можете сделать новый AB(SomeObject)
. Но вам не нужно об этом говорить, попробуйте.