Java 内部类是指在一个类内部定义的类。内部类的概念与嵌套的 Java 类一起工作,在这些类中使用外部类和内部类。定义内部类的主要类被称为外部类,而所有在外部类内部的类则被称为 Java 内部类。
嵌套类
在 Java 中,就像方法一样,类的变量也可以有另一个类作为其成员。在 Java 中允许在一个类内部编写另一个类。内部书写的类被称为嵌套类,而持有内部类的类被称为外部类。
语法
以下是编写嵌套类的语法。这里,Outer_Demo
是外部类,而 Inner_Demo
是嵌套类。
class Outer_Demo {
class Inner_Demo {
}
}
嵌套类分为两种类型:
-
非静态嵌套类(Non-static nested classes):这些是非静态成员。
-
静态嵌套类(Static nested classes):这些是静态成员。
内部类(非静态嵌套类)
内部类是 Java 中的一种安全机制。我们知道类不能与 private
访问修饰符关联,但如果我们将类作为另一个类的成员,那么内部类就可以被声明为 private
。这也可以用来访问类的私有成员。
内部类的类型
根据定义的方式和位置,内部类有三种类型:
-
-
方法局部内部类(Method-local Inner Class)
-
匿名内部类(Anonymous Inner Class)
创建内部类
创建内部类非常简单。你只需要在一个类内部写另一个类。不同于普通的类,内部类可以是 private
的,并且一旦你声明内部类为 private
,就不能从类外部的对象访问它。
以下是一个创建内部类并访问它的程序。在这个例子中,我们使内部类 private
并通过一个方法访问它。
class Outer_Demo {
int num;
private class Inner_Demo {
public void print() {
System.out.println("这是一个内部类");
}
}
void display_Inner() {
Inner_Demo inner = new Inner_Demo();
inner.print();
}
}
public class My_class {
public static void main(String args[]) {
Outer_Demo outer = new Outer_Demo();
outer.display_Inner();
}
}
如果你编译并执行上述程序,你将得到以下结果:
这是一个内部类。
访问私有成员
如前所述,内部类也可以用来访问类的私有成员。假设一个类具有私有成员,可以通过在类中编写一个内部类并在内部类的一个方法(例如 getValue()
)中返回私有成员,最后从另一个类(你想从中访问私有成员的类)调用内部类的 getValue()
方法。
为了实例化内部类,首先需要实例化外部类。之后,使用外部类的对象,可以按照以下方式实例化内部类:
Outer_Demo outer = new Outer_Demo();
Outer_Demo.Inner_Demo inner = outer.new Inner_Demo();
以下的程序展示了如何使用内部类访问类的私有成员:
class Outer_Demo {
private int num = 175;
public class Inner_Demo {
public int getNum() {
System.out.println("这是内部类的 getnum 方法");
return num;
}
}
}
public class My_class2 {
public static void main(String args[]) {
Outer_Demo outer = new Outer_Demo();
Outer_Demo.Inner_Demo inner = outer.new Inner_Demo();
System.out.println(inner.getNum());
}
}
如果你编译并执行上述程序,你将得到以下结果:
这是内部类的 getnum 方法: 175
方法局部内部类
在 Java 中,可以在方法内部编写一个类,这将是一个局部类型。像局部变量一样,内部类的作用域仅限于方法内部。
方法局部内部类只能在其定义的方法内部实例化。以下的程序展示了如何使用方法局部内部类:
public class Outerclass {
void my_Method() {
int num = 23;
class MethodInner_Demo {
public void print() {
System.out.println("这是方法内部类 " + num);
}
}
MethodInner_Demo inner = new MethodInner_Demo();
inner.print();
}
public static void main(String args[]) {
Outerclass outer = new Outerclass();
outer.my_Method();
}
}
如果你编译并执行上述程序,你将得到以下结果:
这是方法内部类 23
匿名内部类
没有类名的内部类被称为匿名内部类。在匿名内部类的情况下,我们在声明的同时进行实例化。通常,它们用于重写类或接口的方法。匿名内部类的语法如下:
AnonymousInner an_inner = new AnonymousInner() {
public void my_method() {
........
........
}
};
以下的程序展示了如何使用匿名内部类重写类的方法:
interface Message {
String greet();
}
public class My_class {
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[]) {
My_class obj = new My_class();
obj.displayMessage(new Message() {
public String greet() {
return "Hello";
}
});
}
}
如果你编译并执行上述程序,你将得到以下结果:
Hello, This is an example of anonymous inner class as an argument
匿名内部类示例
匿名内部类是没有类名的内部类。在匿名内部类的情况下,我们同时声明和实例化它们。通常,它们用于重写类或接口的方法。以下是使用匿名内部类重写抽象类方法的示例:
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("这是匿名内部类的一个示例");
}
};
inner.mymethod();
}
}
如果你编译并执行上述程序,你将得到以下结果:
这是匿名内部类的一个示例
同样地,你可以使用匿名内部类来重写具体类的方法以及接口的方法。
匿名内部类作为方法参数
通常,如果一个方法接受一个接口、抽象类或具体类的对象,那么我们可以实现接口、扩展抽象类,并将对象传递给方法。如果是具体类,则可以直接将其传给方法。
但在所有这三种情况下,你可以将匿名内部类传递给方法。以下是将匿名内部类作为方法参数传递的语法:
obj.my_Method(new My_Class() {
public void Do() {
.....
.....
}
});
以下的程序展示了如何将匿名内部类作为方法参数传递:
interface Message {
String greet();
}
public class My_class {
public void displayMessage(Message m) {
System.out.println(m.greet() +
", 这是匿名内部类作为参数的一个示例");
}
public static void main(String args[]) {
My_class obj = new My_class();
obj.displayMessage(new Message() {
public String greet() {
return "Hello";
}
});
}
}
如果你编译并执行上述程序,你将得到以下结果:
Hello, 这是匿名内部类作为参数的一个示例
静态嵌套类
静态内部类是一个嵌套类,它是外部类的一个静态成员。它可以不实例化外部类就直接访问,使用其他静态成员。就像静态成员一样,静态嵌套类无法访问外部类的实例变量和方法。静态嵌套类的语法如下:
class MyOuter {
static class Nested_Demo {
}
}
实例化静态嵌套类与实例化普通内部类略有不同。以下的程序展示了如何使用静态嵌套类:
public class Outer {
static class Nested_Demo {
public void my_method() {
System.out.println("这是我的嵌套类");
}
}
public static void main(String args[]) {
Outer.Nested_Demo nested = new Outer.Nested_Demo();
nested.my_method();
}
}
如果你编译并执行上述程序,你将得到以下结果:
这是我的嵌套类