以下内容为谷歌翻译自https://www.tutorialspoint.com/java/java_innerclasses.htm:
在Java中,就像方法一样,类的变量也可以有另一个类作为其成员。在Java中允许在一个类中编写另一个类。写入的类称为内部类,并且保存内部类的类称为外部类。
语法:
以下是编写嵌套类的语法。在这里,类Outer_Demo是外部类,Inner_Demo类是内部类。
class Outer_Demo { class Nested_Demo { } }
内部类分为两类:
- 非静态内部类 - 这是类的非静态成员。
- 静态内部类 - 这是类的静态成员。
一、内部类(非静态内部类)
内部类是Java中的安全机制。一个类不能与访问修饰符private关联,但是如果将类作为其他类的成员,那么内部类可以被设为私有的。这也用于访问类的私有成员。
内部类有三种类型,具体取决于它们的定义和位置。他们是:
- 内部类
- 方法本地内部类
- 匿名内部类
1、内部类
创建一个内部类是非常简单的。只需要在类中写一个类。与类不同,内部类可以是私有的,一旦声明一个内部类是私有的,就不能从类之外的对象访问它。
以下是创建内部类并访问它的程序。在给定的例子中,使内部类是私有的,并通过一种方法访问类。
示例:
class Outer_Demo { int num; // inner class private class Inner_Demo { public void print() { System.out.println("This is an inner class"); } } // Accessing he inner class from the method within void display_Inner() { Inner_Demo inner = new Inner_Demo(); inner.print(); } } public class My_class { public static void main(String args[]) { // Instantiating the outer class Outer_Demo outer = new Outer_Demo(); // Accessing the display_Inner() method. outer.display_Inner(); } }
在这里可以看到,Outer_Demo是外部类,Inner_Demo是内部类,display_Inner()是正在实例化内部类的方法,并且从main方法调用此方法。
如果编译并执行上述程序,您将获得以下结果:
This is an inner class.
访问私人会员:
如前所述,内部类也用于访问类的私有成员。假设一个类有私人成员访问它们。在其中编写一个内部类,从内部类的方法返回私有成员,例如getValue(),最后从另一个类(要从中访问私有成员)调用内部类的getValue()方法类。
要实例化内部类,最初必须实例化外部类。此后,使用外部类的对象,以下是实例化内部类的方式。
Outer_Demo outer = new Outer_Demo(); Outer_Demo.Inner_Demo inner = outer.new Inner_Demo();
以下程序显示如何使用内部类访问类的私有成员。
示例:
class Outer_Demo { // private variable of the outer class private int num = 175; // inner class public class Inner_Demo { public int getNum() { System.out.println("This is the getnum method of the inner class"); return num; } } } public class My_class2 { public static void main(String args[]) { // Instantiating the outer class Outer_Demo outer = new Outer_Demo(); // Instantiating the inner class Outer_Demo.Inner_Demo inner = outer.new Inner_Demo(); System.out.println(inner.getNum()); } }
如果编译并执行上述程序,将获得以下结果:
The value of num in the class
175
2、方法本地内部类
在Java中,可以在方法中编写一个类,这将是本地类。像局部变量一样,内部类的范围在方法内受到限制。
方法局部内部类只能在定义内部类的方法中实例化。以下程序显示如何使用方法本地内部类。
示例:
public class Outerclass { // instance method of the outer class void my_Method() { final int num = 23; // method-local inner class class MethodInner_Demo { public void print() { System.out.println("This is method inner class "+num); } } // end of inner class // Accessing the inner class MethodInner_Demo inner = new MethodInner_Demo(); inner.print(); } public static void main(String args[]) { Outerclass outer = new Outerclass(); outer.my_Method(); } }
如果编译并执行上述程序,将获得以下结果:
This is method inner class 23
3、匿名内部类
被声明为没有类名的内部类被称为匿名内部类。在匿名内部类的情况下,同时声明和实例化它们。通常,当需要覆盖类或接口的方法时,它们将被使用。匿名内部类的语法如下:
语法:
AnonymousInner an_inner = new AnonymousInner() { public void my_method() { ........ ........ } };
以下程序显示如何使用匿名内部类覆盖类的方法。
示例:
abstract class AnonymousInner { public abstract void mymethod(); } public class Outer_class { public static void main(String args[]) { AnonymousInner inner = new AnonymousInner() { public void mymethod() { System.out.println("This is an example of anonymous inner class"); } }; inner.mymethod(); } }
如果编译并执行上述程序,将获得以下结果:
This is an example of anonymous inner class
以同样的方式,可以覆盖具体类的方法以及使用匿名内部类的接口。
匿名内部类作为论证:
一般来说,如果方法接受接口的对象,抽象类或具体类,那么可以实现接口,扩展抽象类,并将对象传递给方法。如果是一个类,那么可以直接将它传递给该方法。
但是在所有这三种情况下,可以将匿名内部类传递给该方法。这是传递一个匿名内部类作为方法参数的语法:
obj.my_Method(new My_Class() { public void Do() { ..... ..... } });
以下程序显示如何传递匿名内部类作为方法参数。
示例:
// interface interface Message { String greet(); } public class My_class { // method which accepts the object of interface Message public void displayMessage(Message m) { System.out.println(m.greet() + ", This is an example of anonymous inner class as an argument"); } public static void main(String args[]) { // Instantiating the class My_class obj = new My_class(); // Passing an anonymous inner class as an argument obj.displayMessage(new Message() { public String greet() { return "Hello"; } }); } }
如果编译并执行上面的程序,它会是以下结果:
Hello This is an example of anonymous inner class as an argument
4、静态内部类
静态内部类是一个嵌套类,它是外部类的静态成员。可以使用其他静态成员访问外部类。就像静态成员一样,静态嵌套类无法访问外部类的实例变量和方法。静态嵌套类的语法如下:
语法:
class MyOuter { static class Nested_Demo { } }
实例化静态嵌套类与实例化内部类有一点不同。以下程序显示如何使用静态嵌套类。
示例:
public class Outer { static class Nested_Demo { public void my_method() { System.out.println("This is my nested class"); } } public static void main(String args[]) { Outer.Nested_Demo nested = new Outer.Nested_Demo(); nested.my_method(); } }
如果编译并执行上述程序,将获得以下结果:
This is my nested class
测试工程:https://github.com/easonjim/5_java_example/tree/master/javabasicstest/test16