跳到主要内容

Java 嵌套和内部类

提示
  1. 定义嵌套类:在 Java 中,可以在一个类(外部类)内定义另一个类(嵌套类),包括非静态嵌套类(内部类)和静态嵌套类。
  2. 非静态嵌套类(内部类):内部类可以访问外部类的成员,且必须在外部类实例化后才能实例化。
  3. 静态嵌套类:与内部类不同,静态嵌套类不能访问外部类的非静态成员,且可以直接通过外部类名创建实例。

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

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

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

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

推荐阅读

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

非静态嵌套类(内部类)

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

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

以下是如何在 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

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

在 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;

// 通过构造器赋值
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 的对象
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 关键字来访问外部类的 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 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());
}
}

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

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

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

需要记住的关键点

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