Java 嵌套和内部类

Java 中的内部类分为非静态内部类和静态内部类。在本教程中,我们将通过示例学习 Java 中的内部类和静态内部类。

在本教程中,我们将通过示例学习 Java 中的内部类。

在 Java 中,您可以在另一个类中定义一个类。这样的类被称为 内部类 。 例如,

// 常规类
public class OuterClass {
    // 内部类
    class NestedClass {
        // ...
    }
}

您可以在 Java 中创建两种类型的内部类。

  • 非静态内部类
  • 静态内部类

相关知识点:

我们先来看看非静态内部类。

非静态内部类

非静态内部类是另一个类中的类。它可以访问外部类的成员。它通常被称为 内部类

由于 内部类 存在于外部类中,您必须先实例化外部类,才能实例化内部类。

下面是如何在 Java 中声明内部类的示例。

示例 1:内部类

public class CPU {
    double price;
    // 内部类
    class Processor{

        // 内部类成员
        double cores;
        String manufacturer;

        double getCache(){
            return 4.3;
        }
    }

    // protected 内部类
    protected class RAM{

        // 内部类成员
        double memory;
        String manufacturer;

        double getClockSpeed(){
            return 5.5;
        }
    }
}

public class Main {
    public static void main(String[] args) {

        // create object of Outer class CPU
        CPU cpu = new CPU();

       // create an object of 内部类 Processor using outer class
        CPU.Processor processor = cpu.new Processor();

        // create an object of 内部类 RAM using outer class CPU
        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

在上面的程序中,在外部类 CPU (中央处理器) 中有两个嵌套的类: Processor (处理器) 和 RAM (内存)。 我们将 RAM 类声明为受保护的。

Main 类中,

  1. 首先,我们创建了一个外部类 CPU 的实例 cpu

  2. 然后,我们使用外部类的实例创建内部类的对象:

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

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

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

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

示例 2:访问成员

class Car {
    String carName;
    String carType;

    // 使用构造方法初始化
    public Car(String name, String type) {
        this.carName = name;
        this.carType = type;
    }

    // 私有方法
    private String getCarName() {
        return this.carName;
    }

    // 内部类
    class Engine {
        String engineType;
        void setEngine() {

            // 访问 Car 的 carType
            if(Car.this.carType.equals("4WD")){

                // 调用 Car 的 getCarName() 方法
                if(Car.this.getCarName().equals("Crysler")) {
                    this.engineType = "Smaller";
                } else {
                    this.engineType = "Bigger";
                }

            }else{
                this.engineType = "Bigger";
            }
        }
        String getEngineType(){
            return this.engineType;
        }
    }
}

public class Main {
    public static void main(String[] args) {

        // 创建外部类的对象
        Car car1 = new Car("Mazda", "8WD");

        // 创建内部类的对象
        Car.Engine engine = car1.new Engine();
        engine.setEngine();
        System.out.println("Engine Type for 8WD= " + engine.getEngineType());

        Car car2 = new Car("Crysler", "4WD");
        Car.Engine c2engine = car2.new Engine();
        c2engine.setEngine();
        System.out.println("Engine Type for 4WD = " + c2engine.getEngineType());
    }
}

输出

Engine Type for 8WD= Bigger
Engine Type for 4WD = Smaller

在上面的程序中,我们外部类 Car 内部 车有一个名为 Engine 内部类。请注意下面这行代码:

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

我们使用 this 关键字来访问外部类的变量。您可能已经注意到,我们使用了 Car.this.carType 而不是 this.carType

这是因为如果我们不是用外部类的名称 Car, 那么 this 关键字将代表内部类对象。

同样,我们也按照下面的方法从内部类访问外部类的方法:

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

需要注意的是,虽然 getCarName() 是一个外部类的 private 方法,但我们可以从内部类访问它。

静态内部类

在 Java 中,我们在内部类前面添加 static 关键字,这样的类在术语上被称为静态嵌套类,也称为静态内部类

静态内部类与外部类可以看作两个独立的类,只是从代码层面,静态内部类属于外部类的一部分。这往往是由于静态内部类只有外部类一个使用者,才将它放在外部类的内部。

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

我们可以通过如下方式简单的创建静态内部类对象:

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

示例 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(){
           // 访问外部类的属性
           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());
   }
}

当我们尝试运行程序时,我们会得到一个错误:

java: 无法从静态上下文中引用非静态 变量 this

如需了解更多关于静态内部类的内容,请点击:[Java 静态内部类](../static-class/index.md。

总结

  • Java 将内部类视为类的常规成员。它们就像在类中声明的方法和变量一样。
  • 由于内部类是外部类的成员,因此您可以将任何访问修饰符,例如 private , protected 应用于您的内部类,这在普通类中是不可能的。
  • 由于内部类是外部类的成员,因此您可以使用点 (.) 操作符访问内部类及其成员。
  • 使用内部类将使您的代码更具可读性并提供更好的封装。
  • 非静态内部类可以访问外部类的所有成员,包括私有成员。
  • 静态内部类与外部类是独立的两个类,不可以访问外部类的常规成员,只能访问外部类的静态成员。