Рубрики

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

Внутренний класс означает один класс, который является членом другого класса. Есть в основном четыре типа внутренних классов в Java.

1) Вложенный внутренний класс
2) Метод Локальных внутренних классов
3) Анонимные внутренние классы
4) Статические вложенные классы

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

Следующий пример демонстрирует вложенный класс.

class Outer {

   // Простой вложенный внутренний класс

   class Inner {

      public void show() {

           System.out.println("In a nested class method");

      }

   }

}

class Main {

   public static void main(String[] args) {

       Outer.Inner in = new Outer().new Inner();

       in.show();

   }

}

Выход:

In a nested class method

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

class Outer {

   void outerMethod() {

      System.out.println("inside outerMethod");

   }

   class Inner {

      public static void main(String[] args){

         System.out.println("inside inner class Method");

      }

   }

}

Выход:

Error illegal static declaration in inner class 
Outer.Inner public static void main(String[] args) 
modifier ‘static’ is only allowed in constant 
variable declaration 

Интерфейс также может быть вложенным, и у вложенных интерфейсов есть некоторые интересные свойства. Мы рассмотрим вложенные интерфейсы в следующем посте.

Метод Локальные внутренние классы
Внутренний класс может быть объявлен в методе внешнего класса. В следующем примере Inner является внутренним классом в outerMethod ().

class Outer {

    void outerMethod() {

        System.out.println("inside outerMethod");

        // Внутренний класс является локальным для externalMethod ()

        class Inner {

            void innerMethod() {

                System.out.println("inside innerMethod");

            }

        }

        Inner y = new Inner();

        y.innerMethod();

    }

}

class MethodDemo {

    public static void main(String[] args) {

        Outer x = new Outer();

        x.outerMethod();

    }

}

Выход

Inside outerMethod
Inside innerMethod

Метод Локальные внутренние классы не могут использовать локальную переменную внешнего метода, пока эта локальная переменная не объявлена как финальная. Например, следующий код генерирует ошибку компилятора (обратите внимание, что x не является окончательным в externalMethod () и innerMethod () пытается получить к нему доступ)

class Outer {

   void outerMethod() {

      int x = 98;

      System.out.println("inside outerMethod");

      class Inner {

         void innerMethod() {

            System.out.println("x= "+x);

         }

      }

      Inner y = new Inner();

      y.innerMethod();

   }

}

class MethodLocalVariableDemo {

   public static void main(String[] args) {

      Outer x=new Outer();

      x.outerMethod();

   }

}

Выход:

local variable x is accessed from within inner class; 
needs to be declared final

Примечание: локальный внутренний класс не может получить доступ к неконечной локальной переменной до JDK 1.7. Начиная с JDK 1.8, можно получить доступ к неконечной локальной переменной в локальном внутреннем классе метода.

Но следующий код компилируется и работает нормально (обратите внимание, что x на этот раз является окончательным)

class Outer {

   void outerMethod() {

      final int x=98;

      System.out.println("inside outerMethod");

      class Inner {

         void innerMethod() {

            System.out.println("x = "+x);

         }

      }

      Inner y = new Inner();

      y.innerMethod();

   }

}

class MethodLocalVariableDemo {

    public static void main(String[] args){

      Outer x = new Outer();

      x.outerMethod();

    }

}

Выход-:

Inside outerMethod
X = 98 

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

Статические вложенные классы
Статически вложенные классы технически не являются внутренним классом. Они похожи на статический член внешнего класса.

class Outer {

   private static void outerMethod() {

     System.out.println("inside outerMethod");

   }

     

   // Статический внутренний класс

   static class Inner {

     public static void main(String[] args) {

        System.out.println("inside inner class Method");

        outerMethod();

     }

   }

  
}

Выход

inside inner class Method
inside outerMethod 

Анонимные внутренние классы
Анонимные внутренние классы объявляются без какого-либо имени вообще. Они созданы двумя способами.
а) как подкласс указанного типа

class Demo {

   void show() {

      System.out.println("i am in show method of super class");

   }

}

class Flavor1Demo {

  

   // Анонимный класс с Демо в качестве базового класса

   static Demo d = new Demo() {

       void show() {

           super.show();

           System.out.println("i am in Flavor1Demo class");

       }

   };

   public static void main(String[] args){

       d.show();

   }

}

Выход

i am in show method of super class
i am in Flavor1Demo class 

В приведенном выше коде у нас есть два класса Demo и Flavor1Demo. Здесь демо действует как суперкласс, а анонимный класс — как подкласс, оба класса имеют метод show (). В анонимном классе метод show () переопределяется.

а) как реализатор указанного интерфейса

class Flavor2Demo {

  

    // Анонимный класс, который реализует интерфейс Hello

    static Hello h = new Hello() {

        public void show() {

            System.out.println("i am in anonymous class");

        }

    };

  

    public static void main(String[] args) {

        h.show();

    }

}

  

interface Hello {

    void show();

}

Выход:

i am in anonymous class

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

Эта статья предоставлена Паваном Кумаром . Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой теме

Рекомендуемые посты:

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

0.00 (0%) 0 votes