文章目录
1.什么是内部类?
1.1 内部类的定义
《JAVA programming》里这样定义的:
内部类(又叫嵌入类),是一种在其他类的内部定义的类。
如下所示:
public class ShowInnerClass {
private int data;
public void methodOne(){
}
/**
* InnerClass是ShowInnerClass的内部类
*/
class InnerClass{
public void method(){
data++;
methodOne();
}
}
}
InnerClass类在ShowInnerClass类的内部定义,所以InnerClass是ShowInnerClass的内部类。
1.2 内部类的特性
内部类作为定义在类中的类,有着其一定的特殊性。
内部类有下列特性:
1.2.1 内部类有外部变量的直接访问权
内部类可以引用包含在它的外部类中的数据和方法,所以不必把外部类的引用传递给内部类的构造方法,基于这个原因,内部类可以使程序简单明了。
如下面所示,内部类InnerClass可以直接访问外部类的私有变量和方法。
public class ShowInnerClass {
private int data;
private int num;
private void methodOne(){
}
/**
* InnerClass是ShowInnerClass的内部类
*/
class InnerClass{
public void method(){
data++;
methodOne();
}
}
}
1.2.2 内部类的编译文件
内部类只是用来支撑外部类的工作。编译后,他的名称形如“外部类名称
内部类名称
.
c
l
a
s
s
”。例如,
s
h
o
w
I
n
n
e
r
C
l
a
s
s
中内部类
I
n
n
e
r
C
l
a
s
s
,
被编译为
s
h
o
w
I
n
n
e
r
C
l
a
s
s
内部类名称.class”。例如,showInnerClass中内部类InnerClass,被编译为showInnerClass
内部类名称.class”。例如,showInnerClass中内部类InnerClass,被编译为showInnerClass$InnerClass.class。
1.2.3 内部类的成员
内部类可以声明为public,protected,private,其意义与用在类的其他成员上相同。
public class ShowInnerClass {
public ShowInnerClass.InnerClass InnerClass;
private int data;
private int num;
private void methodOne(){
System.out.println("Hello world");
}
public ShowInnerClass(){
InnerClass = new InnerClass();
}
/**
* InnerClass是ShowInnerClass的内部类
*/
class InnerClass{
private int num2;
protected int age;
public void method(){
data++;
methodOne();
}
}
}
1.2.4 静态内部类
内部类可以声明为static的,可以使用外部类的类名来访问静态的内部类,但静态的内部类不能访问外部类的非静态成员。
如果内部类是静态的,使用下列语法可以直接创建它的对象:
外部类.内部类 内部类对象名 = new 外部类.内部类();
示例:
public class StaticInnerClass {
public static int data;
private static void methodOne(){
System.out.println("hello world! ");
}
/**
* InnerClass是ShowInnerClass的内部类
*/
static class InnerClass{
private int num2;
protected int age;
public void method(){
data++;
methodOne();
}
}
}
上面的类中定义了一个静态内部类。
public class StaticInnerTest {
public static void main(String[] args) {
StaticInnerClass.InnerClass innerClass = new StaticInnerClass.InnerClass();
innerClass.method();
}
}
1.2.5 内部类的使用
我们经常在外部类中创建内部类的对象,但也可以从另外的类中创建内部类的对象。如果内部类是非静态的,必须先创建外部类的实例,然后使用下列语法创建内部类的对象:
外部类.内部类 内部类对象名 = 外部类对象.new 内部类();
public class ShowInnerClass {
public ShowInnerClass.InnerClass InnerClass;
private int data;
private int num;
private void methodOne(){
System.out.println("Hello world");
}
public ShowInnerClass(){
InnerClass = new InnerClass();
}
/**
* InnerClass是ShowInnerClass的内部类
*/
class InnerClass{
private int num2;
protected int age;
public void method(){
data++;
methodOne();
}
}
}
上面的类中定义了非静态内部类:
public class InnerTest {
public static void main(String[] args) {
ShowInnerClass showInnerClass = new ShowInnerClass();
ShowInnerClass.InnerClass innerClass = showInnerClass.new InnerClass();
innerClass.method();
}
}
2.我们为什么需要内部类?
有人有问题:内部类要实现的东西,用前面已学的东西也可以实现,为什么要用它?
这个问题粗略的来讲可以从使用环境来解释它。有的地方我们用内部类的方法会更方便,至于是那些地方,现在本人并没有很深的理解。
但是,下面的场景我们可以考虑使用:
在定义POJO接收Json数据时,如果存在嵌套结构,我们可以使用内部类来定义接收,如下实例:
public class BackRequest {
private String transactionId;
private List<Report> reports;
public static class Report{
private String uuid;
private String errorCode;
private String errorDesc;
private String time;
}
}
使用上面的定义,让我们很容易的将Json数据和实体一一对应。
3.匿名内部类
匿名类就是没有名字的子类。因为没有名字,可以使代码更简洁。。例如
Bank是类,下面代码用Bank的一个子类创建对象:
new Bnak(){
...类体
}
实例:
public class NoNameClass {
public int num;
public int age;
public void say(){
System.out.println("say hello");
}
public static void main(String[] args) {
NoNameClass noNameClass = new NoNameClass() {
public void say() {
System.out.println("I am no body");
}
};
noNameClass.say();
}
}
我们可以看出这样使子类的对象的创建更简洁了。但也有一个的局限性,就是一次使用。不能在使用第二次这个类,因为没有名字。
Java基础学习/src/main/java/exa15 · 严家豆/Study - 码云 - 开源中国 (gitee.com)