在 Java 中,某些类可以在其中包含其他类。这样的类称为嵌套类。在其他类中定义的类通常分为两类:静态和非静态。嵌套的非静态类称为内部类。声明为静态的嵌套类称为静态嵌套类。事实上,这里并不复杂,尽管术语看起来有些模糊,有时甚至会让专业软件开发人员感到困惑。
嵌套类和内部类
因此,位于其他类内部的所有类都称为嵌套类。class OuterClass {
...
class NestedClass {
...
}
}
非静态的嵌套类称为内部类,静态的称为静态嵌套类。
class OuterClass {
...
static class StaticNestedClass {
...
}
class InnerClass {
...
}
}
因此,所有内部类都是嵌套的,但并非所有嵌套都是内部的。这些是主要的定义。内部类是Java中的一种安全机制。我们知道普通的类不能与私有访问修饰符关联。但是,如果我们的类是另一个类的成员,那么可以将内部类设为私有。此功能还用于访问私有类成员。
内部类示例
因此,让我们尝试创建一些类,并在其中创建另一个类。想象某种模块化游戏机。本身有一个“盒子”,某些模块可以连接到它。例如,游戏控制器、方向盘、VR 头盔,通常没有控制台本身就无法工作。这里我们有 GameConsole 类。它有 2 个字段和 1 个方法 — start()。GameCosole和我们习惯的类的区别在于它有一个内部的GameController类。public class GameConsole {
private String model;
private int weight;
public void run() {
System.out.println("Game console is on");
}
public class GameController {
private String color;
public void start() {
System.out.println("start button is pressed");
}
public void x() {
System.out.println("x button is pressed");
}
public void y() {
System.out.println("y button is pressed");
}
public void a() {
System.out.println("a button is pressed");
}
public void b() {
System.out.println("b button is pressed");
}
public void mover() {
System.out.println("mover button is pressed");
}
}
}
此时,您可能想知道:为什么不将这些类“分开”呢?没有必要让它们嵌套。确实有可能。相反,它是关于类在使用方面的正确设计。创建内部类是为了在程序中突出显示与另一个实体密不可分的实体。控制器或 VR 头盔等都是控制台的组件。是的,它们可以与控制台分开购买,但没有它就无法使用。如果我们将所有这些类设为单独的公共类,我们的程序可能具有例如以下代码:
public class Main {
public static void main(String[] args) {
GameController controller = new GameController();
controller.x();
}
}
在这种情况下会发生什么尚不清楚,因为如果没有控制台,控制器本身就无法工作。我们创建了一个游戏控制台对象。我们创建了它的子对象——游戏控制器。现在我们可以玩了,只需按正确的键即可。我们需要的方法在正确的对象上调用。一切都简单又方便。在这个例子中,提取游戏控制器增强了封装性(我们将控制台部分的细节隐藏在相应的类中),并允许更详细的抽象。但是,例如,如果我们创建一个程序来模拟一家可以单独购买 VR 头盔或控制器的商店,那么这个示例就会失败。最好单独创建一个游戏控制器。我们再举一个例子。我们上面提到,我们可以将内部类设为私有,但仍然可以从外部类中调用它。下面是此类的一个示例。
class OuterClass {
// inner class
private class InnerClass {
public void print() {
System.out.println("We are in the inner class...");
}
}
// method of outer class. We are create an inner class from the method of outer one
void display() {
InnerClass inner = new InnerClass();
inner.print();
}
}
这里OuterClass是外部类,InnerClass是内部类,display()是我们在其中创建内部类对象的方法。现在让我们编写一个带有 main 方法的演示类,我们将在其中调用display()方法。
public class OuterDemoMain {
public static void main(String args[]) {
// create an object of the outer class
OuterDemo outer = new OuterDemo();
outer.display();
}
}
如果运行该程序,您将得到以下结果:
我们在内部班...
内部类分类
内部类本身或嵌套的非静态类分为三组。- 内部类照原样。正如我们上面通过GameConsole和GameController示例演示的那样,只有一个非静态类位于另一个类中。
- 方法局部内部类是方法内部的类。
- 匿名内部类。
方法本地内部类
在 Java 中,您可以在方法中编写类,它是本地类型。与局部变量一样,内部类的范围仅限于方法内。方法局部内部类只能在定义该内部类的方法内创建。我们来演示一下如何使用本地方法内部类。public class OuterDemo2 {
//instance method of the outer class OuterDemo2
void myMethod() {
String str = "and it's a value from OuterDemo2 class' myMethod ";
// method-local inner class
class methodInnerDemo {
public void print() {
System.out.println("Here we've got a method inner class... " );
System.out.println(str);
}
}
// Access to the inner class
methodInnerDemo inn = new methodInnerDemo();
inn.print();
}
}
现在我们将编写一个带有 main 方法的演示类,我们将在其中调用external()方法。
public class OuterDemoMain {
public static void main(String args[]) {
OuterDemo2 outer = new OuterDemo2();
outer.myMethod();
}
}
输出是:
这里我们有一个方法内部类...它是来自 OuterDemo2 类的 myMethod 的值
匿名内部类
没有类名声明的内部类称为匿名内部类。当我们声明一个匿名内部类时,我们立即实例化它。通常,每当您需要重写类或接口方法时,就会使用此类。abstract class OuterDemo3 {
public abstract void method();
}
class outerClass {
public static void main(String args[]) {
OuterDemo3 inner = new OuterDemo3() {
public void method() {
System.out.println("Here we've got an example of an anonymous inner class");
}
};
inner.method();
}
}
输出在这里:
这里我们有一个匿名内部类的例子......
匿名内部类作为参数
您还可以将匿名内部类作为参数传递给该方法。这是一个例子。interface OuterDemo4 {
String hello();
}
class NewClass {
// accepts the object of interface
public void displayMessage(OuterDemo4 myMessage) {
System.out.println(myMessage.hello());
System.out.println("example of anonymous inner class as an argument");
}
public static void main(String args[]) {
NewClass newClass = new NewClass();
//here we pass an anonymous inner class as an argument
newClass.displayMessage(new OuterDemo4() {
public String hello() {
return "Hello!";
}
});
}
}
输出在这里:
你好!匿名内部类作为参数的示例
为了巩固您所学到的知识,我们建议您观看我们的 Java 课程中的视频课程
GO TO FULL VERSION