Рубрики
Без рубрики

Внутренний класс Java

Внутренний класс Java. Вложенные классы Java – статический вложенный класс. Внутренний класс Java, локальный внутренний класс, анонимный внутренний класс на java. пример кода и преимущества.

Автор оригинала: Pankaj Kumar.

Внутренний класс Java определяется внутри тела другого класса. Внутренний класс Java может быть объявлен закрытым, общедоступным, защищенным или с доступом по умолчанию, в то время как внешний класс может иметь только открытый доступ или доступ по умолчанию.

Вложенные классы Java делятся на два типа.

  1. статический вложенный класс

    Если вложенный класс статичен, то он называется статическим вложенным классом. Статические вложенные классы могут получать доступ только к статическим членам внешнего класса. Статический вложенный класс такой же, как и любой другой класс верхнего уровня, и вложен только для удобства упаковки.

    Статический объект класса может быть создан с помощью следующей инструкции.

  2. внутренний класс java

    Любой нестатический вложенный класс в java известен как внутренний класс. Внутренний класс Java связан с объектом класса, и они могут получить доступ ко всем переменным и методам внешнего класса.

    Поскольку внутренние классы связаны с экземпляром, в них не может быть никаких статических переменных.

    Объект внутреннего класса java является частью объекта внешнего класса, и для создания экземпляра внутреннего класса нам сначала нужно создать экземпляр внешнего класса.

    Внутренний класс Java может быть создан следующим образом;

Существует два особых вида внутренних классов Java.

  1. локальный внутренний класс

    Если класс определен в теле метода, он называется локальным внутренним классом.

    Поскольку локальный внутренний класс не связан с объектом, мы не можем использовать с ним модификаторы закрытого, открытого или защищенного доступа. Единственными разрешенными модификаторами являются абстрактные или окончательные.

    Локальный внутренний класс может получить доступ ко всем членам заключающего класса и локальным конечным переменным в определенной области. Кроме того, он также может получить доступ к конечным локальным переменным метода, в котором он определен, но не может их изменить. Поэтому, если вы попытаетесь напечатать значение конечной локальной переменной, это будет разрешено, но если вы попытаетесь изменить ее значение внутри локального внутреннего класса метода, вы получите ошибку во время компиляции.

    Локальный внутренний класс может быть определен как:

    Мы также можем определить локальный внутренний класс внутри любого блока, такого как статический блок, блок if-else и т. Д. Однако в этом случае область применения класса будет очень ограниченной.

  2. анонимный внутренний класс

    Локальный внутренний класс без имени известен как анонимный внутренний класс. Анонимный класс определяется и создается в одном операторе.

    Анонимный внутренний класс всегда расширяет класс или реализует интерфейс. Поскольку анонимный класс не имеет имени, невозможно определить конструктор для анонимного класса.

    Анонимные внутренние классы доступны только в том месте, где они определены. Немного сложно определить, как создать анонимный внутренний класс, мы увидим, как он используется в режиме реального времени в приведенной ниже тестовой программе.

Вот класс 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

  1. Если класс полезен только для одного класса, имеет смысл сохранить его вложенным и объединенным. Это помогает в упаковке занятий.
  2. Внутренние классы Java реализуют инкапсуляцию. Обратите внимание, что внутренние классы могут получать доступ к закрытым членам внешнего класса, и в то же время мы можем скрыть внутренний класс от внешнего мира.
  3. Сохранение небольшого класса в классах верхнего уровня приближает код к тому месту, где он используется, и делает код более читаемым и доступным для обслуживания.

Это все для внутреннего класса java.