你好!我们继续探讨 Java 中嵌套类的主题。在上一个练习中,我们谈到了非静态嵌套类,也称为内部类。
今天我们继续讨论另一组类。我们将考虑静态嵌套类。
他们与其他班级有何不同?在声明此类类时,我们使用您已经熟悉的 static 关键字:
在这个例子中,我们有
正如我们在上一课中所说,创建这样一个嵌套类可以提高封装性并有助于实现更现实的抽象。静态和非静态嵌套类有什么区别?1.静态类的对象


public class Boeing737 {
private int manufactureYear;
private static int maxPassengersCount = 300;
public Boeing737(int manufactureYear) {
this.manufactureYear = manufactureYear;
}
public int getManufactureYear() {
return manufactureYear;
}
public static class Drawing {
public static int getMaxPassengersCount() {
return maxPassengersCount;
}
}
}

Boeing737
外部类,它代表这种类型的飞机。它有一个带有一个参数的构造函数:制造年份 ( int manufactureYear
)。还有一个静态变量:最大乘客数 ( int maxPassengersCount
)。对于同一模型的所有平面,它将具有相同的值,因此我们只需要一个实例。此外,它还有一个静态嵌套类:(Drawing
代表飞机的工程蓝图)。我们用这个类来封装飞机的所有官方信息。在我们的示例中,为简单起见,我们将此类限制为制造年份,但它可能包含许多其他信息。 
Drawing
不存储对外部类的具体实例的引用。还记得上节课的自行车例子吗:
public class Bicycle {
private String model;
private int maxWeight;
public Bicycle(String model, int maxWeight) {
this.model = model;
this.maxWeight = maxWeight;
}
public void start() {
System.out.println("Let's go!");
}
public class Handlebar {
public void right() {
System.out.println("Steer right!");
}
public void left() {
System.out.println("Steer left!");
}
}
}
在那节课中,我们谈到了这样一个事实,即Handlebar
内部类的每个实例都在不知不觉中传递了对外部类实例的引用Bicycle
。没有外部类的实例,内部类的对象就不可能存在。对于静态嵌套类,情况并非如此。静态嵌套类的对象完全能够独立存在。在这方面,静态类比非静态类更“独立”。您唯一需要知道的是,在创建这样一个对象时,您必须指定外部类的名称:
public class Main {
public static void main(String[] args) {
Boeing737.Drawing drawing1 = new Boeing737.Drawing();
Boeing737.Drawing drawing2 = new Boeing737.Drawing();
}
}
为什么我们Drawing
在上一课中将类设为静态Seat
类(代表自行车座)非静态?和上次一样,让我们添加一点“哲学”来理解这个例子:) 与自行车座椅不同,工程图的概念并没有严格地与飞机的概念联系在一起。如果没有自行车,一个单独的自行车座椅对象通常是没有意义的(尽管并非总是如此,我们在上一节课中谈到了这一点)。工程图的概念本身就很有意义。例如,它可能对规划飞机维护的工程师很有用。飞机不需要制定计划,可以位于任何地方。只需要工程图。此外,同一型号的所有飞机都将具有相同的工程师图纸,因此不存在与自行车座椅之间的紧密关系。因此,一个Drawing
对象不需要对特定飞机对象的引用。2.外部类的变量和方法的访问方式不同。静态嵌套类只能访问外部类的静态字段。在我们的示例中,该类Drawing
有一个返回外部类getMaxPassengersCount()
静态变量值的方法。maxPassengersCount
但是,我们不能getManufactureYear()
在Drawing
类中创建方法来返回 的值manufactureYear
。毕竟,manufactureYear
变量是非静态的,这意味着它必须属于 的特定实例Boeing737
。而且正如我们已经发现的那样,在静态嵌套类的情况下,外部类的对象很容易不存在。因此,限制 :) 静态变量在外部类中具有哪个访问修饰符并不重要。即使是private
,静态嵌套类仍然可以访问。以上所有内容不仅适用于访问静态变量,也适用于静态方法。 重要的!在内部类的声明中,static
关键字并不意味着只能创建一个对象。不要混淆对象和变量。如果我们谈论的是静态变量,那么,是的,存在静态类变量的单个实例,例如maxPassangersCount
. 但是当static
应用于嵌套类时,仅表示其对象不包含对外部类对象的引用。我们可以根据需要创建尽可能多的对象:
public class Boeing737 {
private int manufactureYear;
private static int maxPassengersCount = 300;
public Boeing737(int manufactureYear) {
this.manufactureYear = manufactureYear;
}
public int getManufactureYear() {
return manufactureYear;
}
public static class Drawing {
private int id;
public Drawing(int id) {
this.id = id;
}
public static int getPassengersCount() {
return maxPassengersCount;
}
@Override
public String toString() {
return "Drawing{" +
"id=" + id +
'}';
}
public static void main(String[] args) {
for (int i = 1; i < 6; i++) {
Boeing737.Drawing drawing = new Boeing737.Drawing(i);
System.out.println(drawing);
}
}
}
}
我们main()
直接在嵌套类中声明该方法(没有特殊原因——只是为了让您知道这是可能的),并创建了 5 个Drawing
对象。尽管我们没有外部类的单个对象。如您所见,这没有造成任何问题 :) 控制台输出:
Drawing{id=1}
Drawing{id=2}
Drawing{id=3}
Drawing{id=4}
Drawing{id=5}
我们的课程到此结束!为了以防万一,我会在 Oracle 文档中为您提供有关它们的部分的链接。如果仍然不清楚,请阅读。现在是我解决几个任务的时候了!:)
GO TO FULL VERSION