English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Tutoriais Básicos de Java

Controle de fluxo Java

Java Array

Java Orientação a Objetos (I)

Java Orientação a Objetos (II)

Java Orientação a Objetos (III)

Tratamento de Exceções Java

Java Lista (List)

Java Fila (Queue)

Java Mapa (Map)

Java Conjunto (Set)

Java Entrada e Saída (I/O)

Java Reader/Writer

Outros tópicos do Java

Classe Aninhada e Classe Interna Java

Neste tutorial, você aprenderá sobre classes aninhadas em Java através de exemplos e seus tipos.

No Java, você pode definir uma classe dentro de outra classe. Essa classe é chamada de nested class (classe aninhada). Por exemplo,

class OuterClass {
    // ...
    class NestedClass {
        // ...
    }
}

您可以使用Java创建两种类型的嵌套类。

  • 非静态嵌套类(内部类)

  • 静态嵌套类

相关阅读:

首先让我们看一下非静态嵌套类。

非静态嵌套类(内部类)

非静态嵌套类是另一个类中的一个类。它有权访问封闭类(外部类)的成员。它通常被称为inner class(内部类)。

由于内部类存在于外部类中,因此必须首先实例化外部类,以便实例化内部类。

这是一个如何在Java中声明内部类的示例。

示例1:内部类

class CPU {
    double price;
    // 嵌套类
    class Processor{
        //嵌套类的成员
        double cores;
        String manufacturer;
        double getCache(){
            return 4.3;
        }
    }
    //嵌套受保护的类
    protected class RAM{
        //受保护的嵌套类的成员
        double memory;
        String manufacturer;
        double getClockSpeed(){
            return 5.5;
        }
    }
}
public class Main {
    public static void main(String[] args) {
        //创建外部类CPU的对象
        CPU cpu = new CPU();
       //使用外部类创建内部类Processor的对象
        CPU.Processor processor = cpu.new Processor();
        //使用外部类CPU创建内部类RAM的对象
        CPU.RAM ram = cpu.new RAM();
        System.out.println("Processor Cache = "); + processor.getCache());
        System.out.println("Ram Clock speed = "); + ram.getClockSpeed());
    }
}

输出:

Processor Cache = 4.3
Ram Clock speed = 5.5

在上面的程序中,有两个嵌套类:Processor和RAM在外部类CPU内部:。我们可以将内部类声明为受保护的。因此,我们已将RAM类声明为受保护的。

在Main类里面

  • 我们首先创建一个名为cpu的外部类CPU的实例。

  • 然后,使用外部类的实例,创建内部类的对象: 

    CPU.Processor processor = cpu.new Processor();
    CPU.RAM ram = cpu.new RAM();

注意:我们使用点(.)运算符使用外部类创建内部类的实例。

访问内部类中的外部类成员

我们可以使用this关键字访问外部类的成员。如果您想了解这个关键字,请访问Java this关键字。}} 

示例2:Acessar membros

class Car {
    String carName;
    String carType;
    //Atribuição de valor usando construtor
    public Car(String name, String type) {
        this.carName = name;
        this.carType = type;
    }
    // Método privado
    private String getCarName() {
        return this.carName;
    }
    //Classe interna
    class Engine {
        String engineType;
        void setEngine() {
           //Acessar a propriedade carType da Car
            if(Car.this.carType.equals("4WD"));
                //Chamar o método getCarName() da Car
                if(Car.this.getCarName().equals("Crysler")) {
                    this.engineType = "Smaller";
                }
                    this.engineType = "Bigger";
                }
            }
                this.engineType = "Bigger";
            }
        }
        String getEngineType() {
            return this.engineType;
        }
    }
}
public class Main {
    public static void main(String[] args) {
        //Criar objeto da classe externa Car
        Car car1 = new Car("Mazda", "8WD");
        //Criar objeto da classe interna usando a classe externa
        Car.Engine engine = car1.new Engine();
        engine.setEngine();
        System.out.println("8WD tipo de motor = " + engine.getEngineType());
        Car car2 = new Car("Crysler", "4WD");
        Car.Engine c2engine = car2.new Engine();
        c2engine.setEngine();
        System.out.println("4WD tipo de motor = " + c2engine.getEngineType());
    }
}

输出:

8WD tipo de motor = Bigger
4WD tipo de motor = Smaller

No programa acima, temos uma classe interna chamada Engine na classe externa Car. Aqui, note esta linha,

if(Car.this.carType.equals("4WD")) { ... }

Usamos o keyword this para acessar a variável carType da classe externa. Você pode ter notado que usamos Car.this.carType em vez de this.carType.

Isso é porque, se não mencionarmos o nome da classe externa Car, o keyword this representará o membro da classe interna.

同样,我们也从内部类访问外部类的方法。

if (Car.this.getCarName().equals("Crysler") {...

需要注意的是,尽管getCarName()是一个private方法,但我们能够从内部类访问它。

静态嵌套类

在Java中,我们还可以在另一个类中定义一个静态(static)类。 这种类称为静态嵌套类(static nested class)。 静态嵌套类不称为静态内部类。

与内部类不同,静态嵌套类无法访问外部类的成员变量。这是因为静态嵌套类不需要您创建外部类的实例。

OuterClass.NestedClass obj = new OuterClass.NestedClass();

在这里,我们仅通过使用外部类的类名来创建静态嵌套类的对象。因此,不能使用OuterClass.this引用外部类。

示例3:静态内部类

class MotherBoard {
   //静态嵌套类
   static class USB{
       int usb2 = 2;
       int usb3 = 1;
       int getTotalPorts(){
           return usb2 + usb3;
       }
   }
}
public class Main {
   public static void main(String[] args) {
       //创建静态嵌套类的对象
       //使用外部类的名称
       MotherBoard.USB usb = new MotherBoard.USB();
       System.out.println("Total Ports = ", + usb.getTotalPorts());
   }
}

输出:

Total Ports = 3

在上面的程序中,我们在类MotherBoard中创建了一个名为USB的静态类。 注意这一行,

MotherBoard.USB usb = new MotherBoard.USB();

在这里,我们使用外部类的名称创建一个USB对象。

现在,让我们看看如果尝试访问外部类的成员会发生什么:

示例4:在静态内部类内部访问外部类的成员

class MotherBoard {
   String model;
   public MotherBoard(String model) {
       this.model = model;
   }
   //静态嵌套类
   static class USB{
       int usb2 = 2;
       int usb3 = 1;
       int getTotalPorts(){
           //访问外部类的变量model
           if(MotherBoard.this.model.equals("MSI")) {
               return 4;
           }
           else {
               return usb2 + usb3;
           }
       }
   }
}
public class Main {
   public static void main(String[] args) {
       //创建静态嵌套类的对象
       MotherBoard.USB usb = new MotherBoard.USB();
       System.out.println("Total Ports = ", + usb.getTotalPorts());
   }
}

When we try to run the program, an error will occur:

error: non-static variable this cannot be referenced from a static context

This is because we did not use an object of the outer class to create an object of the inner class. Therefore, there is no reference stored in Motherboard.this to the outer class Motherboard.

Points to Remember

  • Java treats inner classes as regular class members. They are like methods and variables declared within a class.

  • Since the inner class is a member of the outer class, any access modifier (such as private, protected) can be applied to the inner class, which is not possible in a regular class.

  • Since the nested class is a member of the enclosing outer class, you can use the dot (.) notation to access the nested class and its members.

  • Using nested classes will make your code more readable and provide better encapsulation.

  • Non-static nested classes (inner classes) can access the outer class/Other members of the enclosed class, even if they are declared as private, are also included.