Внутренний класс Java и статический вложенный класс
Терминология: Вложенные jdk классы делятся на две категории: статические и java нестатический. Вложенные jdk классы, которые объявляются static-class статическими, просто называются статические nested-class вложенные классы. Нестатический вложенные .java классы называются внутренними классы.
В jdk просторечии термины «вложенный» и .java «внутренний» взаимозаменяемы jre большинством программистов, но .java я буду использовать правильный inner-class термин «вложенный класс», который static-class охватывает как внутренний, так inner-classes и статический класс.
Классы nested-class могут быть вложены друг в jdk друга до бесконечности, например. класс A openjdk может содержать класс B, который static-class содержит класс C, который inner-class содержит класс D, и т. д. Однако nested-class более чем один уровень вложенности openjdk классов встречается редко, так java-se как это, как правило, плохой jdk дизайн.
Есть три причины, по oraclejdk которым вы можете создать openjdk вложенный класс:
- организация: иногда кажется наиболее разумным отсортировать класс в пространстве имен другого класса, особенно когда он не будет использоваться ни в каком другом контексте
- доступ: вложенные классы имеют специальный доступ к переменным/полям содержащих их классов (какие именно переменные/поля зависят от типа вложенного класса, внутреннего или статического).
- удобство: необходимость создавать новый файл для каждого нового типа, опять же, утомительна, особенно когда тип будет использоваться только в одном контексте
В Java существует openjdk четыре вида вложенных классов. Вкратце, это:
- статический класс: объявлен как статический член другого класса
- внутренний класс: объявлен как член экземпляра другого класса
- локальный внутренний класс: объявлен внутри метода экземпляра другого класса
- анонимный внутренний класс: как локальный внутренний класс, но написанный как выражение, которое возвращает одноразовый объект
Расскажу подробнее.
Статические классы
Статические nested-class классы проще всего понять, поскольку j2se они не имеют ничего общего nested-class с экземплярами содержащего oraclejdk их класса.
Статический класс nested-classes — это класс, объявленный inner-classes как статический член другого static-classes класса. Как и другие статические javax члены, такой класс на самом j2se деле является просто вешалкой, которая .java использует содержащий класс javax в качестве своего пространства java имен, например, класс Goat, объявленный jre как статический член класса .java Rhino в пакете pizza по названию пицца.Носорог.Коза.
package pizza;
public class Rhino {
...
public static class Goat {
...
}
}
Честно java-se говоря, статические классы nested-class — довольно бесполезная функция, потому jre что классы уже разделены j2se на пространства имен пакетами. Единственная jdk реальная возможная причина java для создания статического oraclejdk класса заключается в том, что jdk такой класс имеет доступ .java к закрытым статическим членам java-se содержащего его класса, но jdk я считаю это довольно неубедительным jdk оправданием существования javax функции статического класса.
Внутренние классы
Внутренний nested-class класс — это класс, объявленный java как нестатический член другого jdk класса:
package pizza;
public class Rhino {
public class Goat {
...
}
private void jerry() {
Goat g = new Goat();
}
}
Как и в случае со inner-class статическим классом, внутренний oraclejdk класс известен как квалифицированный nested-class по имени содержащего его static-class класса, pizza.Rhino.Goat, но внутри содержащего jdk класса он может быть известен inner-class по его простому имени. Однако jre каждый экземпляр внутреннего nested-class класса привязан к конкретному j2se экземпляру содержащего его .java класса: выше, Goat, созданный jre в jerry, неявно связан с экземпляром java-se Rhino this в jerry. В противном случае javax мы делаем связанный экземпляр static-classes Rhino явным при создании экземпляра javax Goat:
Rhino rhino = new Rhino();
Rhino.Goat goat = rhino.new Goat();
(Обратите внимание, что javax вы называете внутренний тип openjdk просто Goat в странном синтаксисе inner-classes new: Java выводит содержащий nested-class тип из части rhino. И, да, new rhino.Goat() имело inner-classes бы больше смысла мне тоже)
Итак, что nested-classes это дает нам? Экземпляр внутреннего j2se класса имеет доступ к членам nested-class экземпляра содержащего экземпляра java-se класса. Эти включающие члены java экземпляра упоминаются внутри j2se внутреннего класса via только jre их простые имена, а не via this (this во java-se внутреннем классе относится java к экземпляру внутреннего nested-classes класса, а не к связанному openjdk экземпляру содержащего класса):
public class Rhino {
private String barry;
public class Goat {
public void colin() {
System.out.println(barry);
}
}
}
Во openjdk внутреннем классе вы можете nested-classes ссылаться на this содержащего inner-class класса как на Rhino.this, и вы можете java-se использовать this для ссылки j2se на его члены, например. Носорог.этот.барри.
Локальные внутренние классы
Локальный javax внутренний класс — это класс, объявленный .java в теле метода. Такой класс j2se известен только в содержащем openjdk его методе, поэтому его можно javax создать и получить доступ nested-class к его членам только в содержащем jdk его методе. Преимущество j2se заключается в том, что локальный inner-classes экземпляр внутреннего класса j2se привязан к конечным локальным inner-class переменным содержащего его .java метода и может получить к javax ним доступ. Когда экземпляр openjdk использует конечный локальный inner-class метод содержащего его метода, переменная core-java сохраняет значение, которое openjdk она имела во время создания static-classes экземпляра, даже если переменная jre вышла за пределы области inner-class видимости (по сути, это грубая, ограниченная jdk версия замыканий в Java).
Поскольку nested-class локальный внутренний класс nested-class не является ни членом класса, ни oraclejdk пакета, он не объявляется static-classes с уровнем доступа. (Обратите j2se внимание, однако, что его static-class собственные члены имеют такие inner-class же уровни доступа, как и openjdk в обычном классе.)
Если локальный static-class внутренний класс объявлен openjdk в методе экземпляра, экземпляр inner-class внутреннего класса привязан inner-class к экземпляру, удерживаемому java-se this содержащего метода во время core-java создания экземпляра, и поэтому openjdk члены экземпляра содержащего inner-class класса доступны как во внутреннем java-se классе экземпляра. Локальный j2se внутренний класс создается static-classes просто через его имя, например локальный static-classes внутренний класс Cat создается openjdk как new Cat(), а не new this.Cat(), как static-class можно было бы ожидать.
Анонимные внутренние классы
Анонимный j2se внутренний класс — синтаксически nested-classes удобный способ записи локального javax внутреннего класса. Чаще javax всего локальный внутренний inner-classes класс создается не более jdk одного раза при каждом запуске inner-classes содержащего его метода. Было jdk бы хорошо, если бы мы могли javax объединить локальное определение static-classes внутреннего класса и его inner-classes единственную реализацию в java одну удобную синтаксическую openjdk форму, и было бы также хорошо, если inner-classes бы нам не нужно было придумывать nested-class имя для класса (чем меньше static-classes бесполезных имена, которые javax содержит ваш код, тем лучше). Анонимный static-class внутренний класс допускает openjdk обе эти вещи:
new *ParentClassName*(*constructorArgs*) {*members*}
Это выражение, возвращающее java новый экземпляр безымянного j2se класса, который расширяет java ParentClassName. Вы не можете предоставить j2se свой собственный конструктор; скорее, неявно core-java предоставляется один, который inner-class просто вызывает суперконструктор, поэтому jdk предоставленные аргументы static-classes должны соответствовать суперконструктору. (Если static-class родительский элемент содержит jdk несколько конструкторов, называется java-se «самый простой» из них, «самый static-classes простой», определяемый довольно java сложным набором правил, которые nested-classes не стоит утруждать себя детальным jre изучением — просто обратите openjdk внимание на то, что вам говорят inner-class NetBeans или Eclipse.)
В качестве j2se альтернативы вы можете указать .java интерфейс для реализации:
new *InterfaceName*() {*members*}
Такое .java объявление создает новый static-class экземпляр безымянного класса, который java-se расширяет Object и реализует inner-class InterfaceName. Опять же, вы не можете inner-classes предоставить свой собственный openjdk конструктор; в этом случае oraclejdk Java неявно предоставляет .java конструктор без аргументов, ничего static-classes не делающий (поэтому в этом .java случае никогда не будет аргументов openjdk конструктора).
Несмотря на java то, что вы не можете дать inner-classes анонимному внутреннему классу j2se конструктор, вы все равно openjdk можете выполнить любую настройку, которую nested-classes хотите, используя блок инициализатора java (блок {}, размещенный вне core-java любого метода).
Уясните, что inner-class анонимный внутренний класс nested-classes — это просто менее гибкий inner-class способ создания локального javax внутреннего класса с одним jdk экземпляром. Если вам нужен openjdk локальный внутренний класс, который jdk реализует несколько интерфейсов java или который реализует интерфейсы, расширяя static-classes какой-либо класс, отличный openjdk от Object, или который указывает jre свой собственный конструктор, вы openjdk застряли в создании обычного jdk именованного локального внутреннего java класса.
java
inner-classes
static-classes
Внутренний класс Java и статический вложенный класс
Мы используем файлы cookies для улучшения работы сайта. Оставаясь на нашем сайте, вы соглашаетесь с условиями использования файлов cookies. Чтобы ознакомиться с нашими Положениями о конфиденциальности и об использовании файлов cookie, нажмите здесь.