Автор оригинала: Pankaj Kumar.
Внутренний класс Java определяется внутри тела другого класса. Внутренний класс Java может быть объявлен закрытым, общедоступным, защищенным или с доступом по умолчанию, в то время как внешний класс может иметь только открытый доступ или доступ по умолчанию.
Вложенные классы Java делятся на два типа.
статический вложенный класс
Если вложенный класс статичен, то он называется статическим вложенным классом. Статические вложенные классы могут получать доступ только к статическим членам внешнего класса. Статический вложенный класс такой же, как и любой другой класс верхнего уровня, и вложен только для удобства упаковки.
Статический объект класса может быть создан с помощью следующей инструкции.
внутренний класс java
Любой нестатический вложенный класс в java известен как внутренний класс. Внутренний класс Java связан с объектом класса, и они могут получить доступ ко всем переменным и методам внешнего класса.
Поскольку внутренние классы связаны с экземпляром, в них не может быть никаких статических переменных.
Объект внутреннего класса java является частью объекта внешнего класса, и для создания экземпляра внутреннего класса нам сначала нужно создать экземпляр внешнего класса.
Внутренний класс Java может быть создан следующим образом;
Существует два особых вида внутренних классов Java.
локальный внутренний класс
Если класс определен в теле метода, он называется локальным внутренним классом.
Поскольку локальный внутренний класс не связан с объектом, мы не можем использовать с ним модификаторы закрытого, открытого или защищенного доступа. Единственными разрешенными модификаторами являются абстрактные или окончательные.
Локальный внутренний класс может получить доступ ко всем членам заключающего класса и локальным конечным переменным в определенной области. Кроме того, он также может получить доступ к конечным локальным переменным метода, в котором он определен, но не может их изменить. Поэтому, если вы попытаетесь напечатать значение конечной локальной переменной, это будет разрешено, но если вы попытаетесь изменить ее значение внутри локального внутреннего класса метода, вы получите ошибку во время компиляции.
Локальный внутренний класс может быть определен как:
Мы также можем определить локальный внутренний класс внутри любого блока, такого как статический блок, блок if-else и т. Д. Однако в этом случае область применения класса будет очень ограниченной.
анонимный внутренний класс
Локальный внутренний класс без имени известен как анонимный внутренний класс. Анонимный класс определяется и создается в одном операторе.
Анонимный внутренний класс всегда расширяет класс или реализует интерфейс. Поскольку анонимный класс не имеет имени, невозможно определить конструктор для анонимного класса.
Анонимные внутренние классы доступны только в том месте, где они определены. Немного сложно определить, как создать анонимный внутренний класс, мы увидим, как он используется в режиме реального времени в приведенной ниже тестовой программе.
Вот класс java, показывающий, как определить внутренний класс java, статический вложенный класс, локальный внутренний класс и анонимный внутренний класс.
Вот класс java, показывающий, как определить внутренний класс java, статический вложенный класс, локальный внутренний класс и анонимный внутренний класс.
package com.journaldev.nested; import java.io.File; import java.io.FilenameFilter; public class OuterClass { private static String name = "OuterClass"; private int i; protected int j; int k; public int l; //OuterClass constructor public OuterClass(int i, int j, int k, int l) { this.i = i; this.j = j; this.k = k; this.l = l; } public int getI() { return this.i; } //static nested class, can access OuterClass static variables/methods static class StaticNestedClass { private int a; protected int b; int c; public int d; public int getA() { return this.a; } public String getName() { return name; } } //inner class, non-static and can access all the variables/methods of the outer class class InnerClass { private int w; protected int x; int y; public int z; public int getW() { return this.w; } public void setValues() { this.w = i; this.x = j; this.y = k; this.z = l; } @Override public String toString() { return "w=" + w + ":x=" + x + ":y=" + y + ":z=" + z; } public String getName() { return name; } } //local inner class public void print(String initial) { //local inner class inside the method class Logger { String name; public Logger(String name) { this.name = name; } public void log(String str) { System.out.println(this.name + ": " + str); } } Logger logger = new Logger(initial); logger.log(name); logger.log("" + this.i); logger.log("" + this.j); logger.log("" + this.k); logger.log("" + this.l); } //anonymous inner class public String[] getFilesInDir(String dir, final String ext) { File file = new File(dir); //anonymous inner class implementing FilenameFilter interface String[] filesList = file.list(new FilenameFilter() { @Override public boolean accept(File dir, String name) { return name.endsWith(ext); } }); return filesList; } }
Вот тестовая программа, показывающая, как создать экземпляр и использовать внутренний класс в java.
Вот тестовая программа, показывающая, как создать экземпляр и использовать внутренний класс в java.
package com.journaldev.nested; import java.util.Arrays; //nested classes can be used in import for easy instantiation import com.journaldev.nested.OuterClass.InnerClass; import com.journaldev.nested.OuterClass.StaticNestedClass; public class InnerClassTest { public static void main(String[] args) { OuterClass outer = new OuterClass(1,2,3,4); //static nested classes example StaticNestedClass staticNestedClass = new StaticNestedClass(); StaticNestedClass staticNestedClass1 = new StaticNestedClass(); System.out.println(staticNestedClass.getName()); staticNestedClass.d=10; System.out.println(staticNestedClass.d); System.out.println(staticNestedClass1.d); //inner class example InnerClass innerClass = outer.new InnerClass(); System.out.println(innerClass.getName()); System.out.println(innerClass); innerClass.setValues(); System.out.println(innerClass); //calling method using local inner class outer.print("Outer"); //calling method using anonymous inner class System.out.println(Arrays.toString(outer.getFilesInDir("src/com/journaldev/nested", ".java"))); System.out.println(Arrays.toString(outer.getFilesInDir("bin/com/journaldev/nested", ".class"))); } }
Вот результат приведенного выше примера программы внутреннего класса java.
OuterClass 10 0 OuterClass w=0:x=0:y=0:z=0 w=1:x=2:y=3:z=4 Outer: OuterClass Outer: 1 Outer: 2 Outer: 3 Outer: 4 [NestedClassTest.java, OuterClass.java] [NestedClassTest.class, OuterClass$1.class, OuterClass$1Logger.class, OuterClass$InnerClass.class, OuterClass$StaticNestedClass.class, OuterClass.class]
Обратите внимание, что при компиляции внешнего класса для внутреннего класса, локального внутреннего класса и статического вложенного класса создаются отдельные файлы классов.
Преимущества внутреннего класса Java
- Если класс полезен только для одного класса, имеет смысл сохранить его вложенным и объединенным. Это помогает в упаковке занятий.
- Внутренние классы Java реализуют инкапсуляцию. Обратите внимание, что внутренние классы могут получать доступ к закрытым членам внешнего класса, и в то же время мы можем скрыть внутренний класс от внешнего мира.
- Сохранение небольшого класса в классах верхнего уровня приближает код к тому месту, где он используется, и делает код более читаемым и доступным для обслуживания.
Это все для внутреннего класса java.