Java 嵌套类和内部类

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

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

在 Java 中,您可以创建两种类型的嵌套类。

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

我们先来看非静态嵌套类。


非静态嵌套类 (内部类)

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

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

以下是声明 Java 内部类的示例。

示例 1: 内部类

class CPU {
    double price;
    // nested class
    class Processor{

        // members of nested class
        double cores;
        String manufacturer;

        double getCache(){
            return 4.3;
        }
    }

    // nested protected class
    protected class RAM{

        // members of protected nested class
        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 inner class Processor using outer class
        CPU.Processor processor = cpu.new Processor();

        // create an object of inner class 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中有两个嵌套类:ProcessorRAM。我们可以将内部类声明为 protected。因此,我们将 RAM 类声明为 protected。

在 Main 类中,

  • 我们首先创建了一个外部类 CPU 的实例,名为 cpu
  • 使用外部类的实例,我们然后创建了内部类的对象
    CPU.Processor processor = cpu.new Processor;
    
    CPU.RAM ram = cpu.new RAM();

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


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

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

示例 2: 访问成员

class Car {
    String carName;
    String carType;

    // assign values using constructor
    public Car(String name, String type) {
        this.carName = name;
        this.carType = type;
    }

    // private method
    private String getCarName() {
        return this.carName;
    }

// inner class
    class Engine {
        String engineType;
        void setEngine() {

           // Accessing the carType property of Car
            if(Car.this.carType.equals("4WD")){

                // Invoking method getCarName() of Car
                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) {

// create an object of the outer class Car
        Car car1 = new Car("Mazda", "8WD");

        // create an object of inner class using the outer class
        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 关键字来访问外部类的 carType 变量。您可能已经注意到,我们没有使用 this.carType,而是使用了 Car.this.carType

这是因为如果我们没有指定外部类 Car 的名称,那么 this 关键字将代表内部类的成员。

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

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

值得注意的是,虽然 getCarName() 是一个 private 方法,但我们可以在内部类中访问它。


静态嵌套类

在 Java 中,我们也可以在另一个类中定义一个 static 类。这样的类被称为静态嵌套类。静态嵌套类不被称为静态内部类。

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

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

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

示例 3: 静态内部类

class MotherBoard {

   // static nested class
   static class USB{
       int usb2 = 2;
       int usb3 = 1;
       int getTotalPorts(){
           return usb2 + usb3;
       }
   }

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

       // create an object of the static nested class
       // using the name of the outer class
       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 nested class
   static class USB{
       int usb2 = 2;
       int usb3 = 1;
       int getTotalPorts(){
           // accessing the variable model of the outer classs
           if(MotherBoard.this.model.equals("MSI")) {
               return 4;
           }
           else {
               return usb2 + usb3;
           }
       }
   }
}
public class Main {
   public static void main(String[] args) {

       // create an object of the static nested class
       MotherBoard.USB usb = new MotherBoard.USB();
       System.out.println("Total Ports = " + usb.getTotalPorts());
   }
}

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

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

这是因为我们没有使用外部类的对象来创建内部类的对象。因此,没有引用存储在 Motherboard.this 中的外部类 Motherboard


要记住的要点

  • Java 将内部类视为类的常规成员。它们就像在类中声明的 方法和变量一样。
  • 由于内部类是外部类的成员,您可以为内部类应用任何访问修饰符,如 privateprotected,这在普通类中是不可能的。
  • 由于嵌套类是其封闭外部类的成员,您可以使用点 (.) 符号来访问嵌套类及其成员。
  • 使用嵌套类可以使您的代码更具可读性,并提供更好的封装。
  • 非静态嵌套类 (内部类) 可以访问外部/封闭类的其他成员,即使它们被声明为 private。

另请阅读:

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战