GrabDuck

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

:

Последнее обновление: 30.10.2015

Внутренние классы представляют такие типы, которые определены внутри других классов. Например, имеется класс Book, внутри которого определен класс Publisher:

class Book{

    String name;
    String author;
    int year;
    public Publisher publisher;

    Book(String name, String author, int year, String publ){
        
        this.name = name;
        this.author = author;
        this.year = year;
        publisher = new Publisher(publ);
    }
    
    class Publisher{
    
        public String name;
        public Book book;
		
        public Publisher(String name){
            book=Book.this;
            this.name=name;
        }
    }
}

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

Внутренний класс имеет доступ ко всем полям внешнего класса, в том числе закрытым с помощью модификатора private. А саму ссылку на внешний класс из внутреннего можно получить с помощью выражения Book.this, где вначале идет имя внешнего класса.

Теперь используем классы:

Book b1 = new Book("Война и мир", "Л. Н. Толстой", 1863, "ХудКнига");
System.out.println(b1.publisher.name);

Объекты внутренних классов могут быть созданы только в том классе, в котором внутренние классы опеределены. В других внешних классах объекты внутреннего класса создать нельзя.

Еще одной особенностей внутренних классов является то, что их можно объявить внутри любого контекста, в том числе внутри метода и даже в цикле:

class Book{

    String name;
    String author;
    int year;

    Book(String name, String author, int year){
        
        this.name = name;
        this.author = author;
        this.year = year;
    }
    public void setPublisher(String publ){
    
        class Publisher{
            void displayInfo(){

                System.out.println("Издатель: " + publ);
            }
        }
        
        Publisher publisher = new Publisher();
        publisher.displayInfo();
    }
}

Затем при использовании нам достаточно вызвать метод setPublisher объекта Book:

Book b1 = new Book("Война и мир", "Л. Н. Толстой", 1863);
b1.setPublisher("ООО ХудКнига");

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

В отличие от обычных классов внутренние классы могут быть статическими. Такие классы еще называют вложенными. Статические внутренние классы позволяют скрыть некоторую комплексную информацию внутри внешнего класса:

class Math{

    public static class Factorial{
    
        private int result;
        private int key;
        
        public Factorial(int number, int x){
            
            result=number;
            key = x;
        }
        
        public int getResult(){
            return result;
        }
        
        public int getKey(){
            return key;
        }
    }
    
    public static Factorial getFactorial(int x){
    
        int result=1;
        for (int i = 1; i <= x; i++){
		
            result *= i;
        }
        return new Factorial(result, x);
    }
}

Здесь определен вложенный класс для хранения данных о вычислении факториала. Основные действия выполняет метод getFactorial, который возвращает объект вложенного класса. И теперь используем классы в методе main:

public static void main(String[] args) {
        
    Math.Factorial fact = Math.getFactorial(6);
    System.out.printf("Факториал числа %d равен %d \n", fact.getKey(), fact.getResult());
}