Внутренние и вложенные классы — это не одно и тоже.
В чем разница, и когда принципиально нужно использовать один, а когда другой?
Статические вложенные классы, не имеют доступа к нестатическим полям и методам обрамляющего класса. Поведение точно такое же, как у статических методов класса. Доступ к нестатическим полям и методам может осуществляться только через ссылку на экземпляр обрамляющего класса.
Но static nested классы имеют доступ к любым статическим методам внешнего класса, в том числе и к приватным.
public class Mememe {
private static int m_AccessableInt; // доступно в StaticNestedMememe
private int m_NotAccessableInt; // не доступно в StaticNestedMememe
[...]
public static class StaticNestedMememe {
[...]
}
}
Применение? Например, если вложенный класс имеет смысл только в контексте обрамляющего класса.
Так же многие используют такие классы для реализации паттерна Builder.
Экземпляр такого класса нужно создавать, используя имя обрамляющего класса:
Mememe.StaticNestedMememe nestedObject = new Mememe.StaticNestedMememe();
Внутренние классы бывают трёх типов:
Локальные классы определяются внутри блока кода.
public class Mememe {
public void calc(String requestPath) {
class Сalculator{
int calc() { return 0; }
}
}
}
Локальные классы имеют доступ к полям и методам обрамляющего класса. Локальные классы:
private
, public
, protected
или
static
;static final
);Анонимный класс (anonymous class) - это локальный класс без имени.
Типичный пример - реализация Runnable
:
new Thread(new Runnable() {
public void run() {
...
}
}).start();
Основное ограничение при использовании анонимных классов - это невозможность описания конструктора, так как класс не имеет имени.
Внутренние классы-члены ассоциируются не с самим внешним классом, а с его экземпляром. При этом они имеют доступ ко всем его полям и методам. Например:
public class OuterClass {
public void method() { ... }
public class InnerClass {
public void method() { ... }
public void anotherMethod() {
method();
}
}
}
InnerClass
имеет доступ в членам класса OuterClass
, как видно на примере метода anotherMethod
, который вызывает метод method
.
Создать такой класс можно так:
OuterClass outer = new OuterClass();
OuterClass.InnerClass innerClass = outer.new InnerClass();
Внутренний (inner):
Вложенный (nested):
Код:
public class Example {
public static int si = 0;
private static int psi = 0;
public final Inner inner;
public int i = 0;
private int pi = 0;
public Example() {
inner = new Inner();
}
public static class Nested {
int e;
public Nested() {
e = Example.psi;
e = Example.si;
// а вот так нельзя
// e = Example.this.pi;
// e = Example.this.i;
}
}
public class Inner {
int e;
public Inner() {
e = Example.psi;
e = Example.si;
e = Example.this.pi;
e = Example.this.i;
}
}
}
class ExampleTwo {
// Nested можно сразу
Example.Nested nested = new Example.Nested();
Example.Inner inner;
{
// так нельзя, нужен объект Example
// inner = new Example.Inner();
// а так можно
Example example = new Example();
inner = example.inner;
}
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Использую связку gulp + wabpack(wabpack-stream) + babel 7