“全栈2019”Java第六十七章:内部类、嵌套类详解

134 阅读12分钟
原文链接: www.toutiao.com

难度

初级

学习时间

30分钟

适合人群

零基础

开发语言

Java

开发环境

  • JDK v11
  • IntelliJ IDEA v2018.3

提示

本教学属于系列教学,内容具有连贯性,本章使用到的内容之前教学中都有详细讲解。

1.内部类

在Java中,我们可以在一个类中再定义一个类,这样称之为内部类。

内部类又称之为嵌套类。

内部类定义格式:

“全栈2019”Java第六十七章:内部类、嵌套类详解

例如:

“全栈2019”Java第六十七章:内部类、嵌套类详解

内部类分为静态内部类和非静态内部类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

2.实例化非静态内部类

内部类分为两类:静态和非静态。 声明为static的内部类称为静态内部类。 非静态内部类称为内部类。

要实例化内部类,必须首先实例化外部类。

演示:

请创建一个外部类Outer,在外部类Outer里面创建一个内部类Inner。

请观察程序运行结果。

代码:

Outer类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

Main类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

结果:

“全栈2019”Java第六十七章:内部类、嵌套类详解

外部类Outer中定义了内部类Inner,由于内部类Inner的访问修饰符是public的,所以我们可以创建内部类Inner的对象。在创建内部类Inner对象时,我们先创建了外部类Outer的对象,然后通过outer实例new创建了内部类Inner对象。创建过程分为了两步,第一步创建外部类对象;第二步通过外部类对象创建内部类对象。还有一种一步到位的创建方式:

“全栈2019”Java第六十七章:内部类、嵌套类详解

上面这种方式只是从写法上看起来一步到位,但是执行过程和分两步没什么区别。

3.内部类中的实例变量

我们可以像定义普通类里面的成员一样来定义内部类里面的成员。

演示:

请创建一个外部类Outer,在外部类Outer里面创建一个内部类Inner。在内部类Inner中定义实例变量。

请观察程序运行结果。

代码:

Outer类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

Main类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

结果:

“全栈2019”Java第六十七章:内部类、嵌套类详解

我们可以在内部类Inner中定义和普通类一样的实例变量,可同时定义private,public,protected或package private四种访问权限的实例变量。在内部类Inner构造方法中我们访问了这些内部类实例变量,从运行结果来看,完全没有问题。同样的我们可不可以在外界创建内部类对象,然后访问内部类实例变量呢?来看看吧:

Outer类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

Main类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

结果:

“全栈2019”Java第六十七章:内部类、嵌套类详解

错误信息:

“全栈2019”Java第六十七章:内部类、嵌套类详解

文字版:

/Users/admin/Workspace/Java/Hello/src/main/Main.javaError:(11, 64) java: anInt 在 lab.Outer.Inner 中是 private 访问控制Error:(12, 65) java: aFloat在lab.Outer.Inner中不是公共的; 无法从外部程序包中对其进行访问Error:(13, 66) java: aDouble 在 lab.Outer.Inner 中是 protected 访问控制

看来,要想访问内部类中的实例变量,只能是公开的访问权限才可以。访问规则和普通类没有什么区别。

4.内部类中的实例方法

我们可以像定义普通类里面的成员一样来定义内部类里面的成员。

演示:

请创建一个外部类Outer,在外部类Outer里面创建一个内部类Inner。在内部类Inner中定义实例方法。

请观察程序运行结果。

代码:

Outer类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

Main类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

结果:

“全栈2019”Java第六十七章:内部类、嵌套类详解

我们可以在内部类Inner中定义和普通类一样的实例方法,可同时定义private,public,protected或package private四种访问权限的实例方法。在内部类Inner构造方法中我们访问了这些内部类实例方法,从运行结果来看,完全没有问题。同样的我们可不可以在外界创建内部类对象,然后访问内部类实例方法呢?来看看吧:

Outer类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

Main类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

结果:

“全栈2019”Java第六十七章:内部类、嵌套类详解

错误信息:

“全栈2019”Java第六十七章:内部类、嵌套类详解

文字版:

/Users/admin/Workspace/Java/Hello/src/main/Main.javaError:(12, 53) java: getIntValue(int) 在 lab.Outer.Inner 中是 private 访问控制Error:(14, 56) java: getFloatValue(float)在lab.Outer.Inner中不是公共的; 无法从外部程序包中对其进行访问Error:(16, 54) java: getBooleanValue(boolean) 在 lab.Outer.Inner 中是 protected 访问控制

看来,要想访问内部类中的实例方法,只能是公开的访问权限才可以。访问规则和普通类没有什么区别。

5.内部类中的常量

我们可以像定义普通类里面的成员一样来定义内部类里面的成员。

演示:

请创建一个外部类Outer,在外部类Outer里面创建一个内部类Inner。在内部类Inner中定义常量。

请观察程序运行结果。

代码:

Outer类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

Main类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

结果:

“全栈2019”Java第六十七章:内部类、嵌套类详解

我们可以在内部类Inner中定义和普通类一样的常量,可同时定义private,public,protected或package private四种访问权限的常量。在内部类Inner构造方法中我们访问了这些内部类常量,从运行结果来看,完全没有问题。同样的我们可不可以在外界创建内部类对象,然后访问内部类常量呢?来看看吧:

Outer类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

Main类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

结果:

“全栈2019”Java第六十七章:内部类、嵌套类详解

错误信息:

“全栈2019”Java第六十七章:内部类、嵌套类详解

文字版:

/Users/admin/Workspace/Java/Hello/src/main/Main.javaError:(11, 58) java: anInt 在 lab.Outer.Inner 中是 private 访问控制Error:(12, 62) java: aFloat在lab.Outer.Inner中不是公共的; 无法从外部程序包中对其进行访问Error:(13, 61) java: aDouble 在 lab.Outer.Inner 中是 protected 访问控制

看来,要想访问内部类中的常量,只能是公开的访问权限才可以。访问规则和普通类没有什么区别。

6.内部类中的最终方法

我们可以像定义普通类里面的成员一样来定义内部类里面的成员。

演示:

请创建一个外部类Outer,在外部类Outer里面创建一个内部类Inner。在内部类Inner中定义最终方法。

请观察程序运行结果。

代码:

Outer类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

Main类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

结果:

“全栈2019”Java第六十七章:内部类、嵌套类详解

我们可以在内部类Inner中定义和普通类一样的最终方法,可同时定义private,public,protected或package private四种访问权限的最终方法。在内部类Inner构造方法中我们访问了这些内部类最终方法,从运行结果来看,完全没有问题。同样的我们可不可以在外界创建内部类对象,然后访问内部类最终方法呢?来看看吧:

Outer类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

Main类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

结果:

“全栈2019”Java第六十七章:内部类、嵌套类详解

错误信息:

“全栈2019”Java第六十七章:内部类、嵌套类详解

文字版:

/Users/admin/Workspace/Java/Hello/src/main/Main.javaError:(11, 57) java: getIntValue(int) 在 lab.Outer.Inner 中是 private 访问控制Error:(12, 60) java: getFloatValue(float)在lab.Outer.Inner中不是公共的; 无法从外部程序包中对其进行访问Error:(13, 58) java: getBooleanValue(boolean) 在 lab.Outer.Inner 中是 protected 访问控制

看来,要想访问内部类中的最终方法,只能是公开的访问权限才可以。访问规则和普通类没有什么区别。

7.内部类中的类变量

我们可以像定义普通类里面的成员一样来定义内部类里面的成员。

演示:

请创建一个外部类Outer,在外部类Outer里面创建一个内部类Inner。在内部类Inner中定义类变量。

请观察程序运行结果。

代码:

Outer类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

Main类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

结果:

“全栈2019”Java第六十七章:内部类、嵌套类详解

错误信息:

“全栈2019”Java第六十七章:内部类、嵌套类详解

文字版:

/Users/admin/Workspace/Java/Hello/src/lab/Outer.javaError:(16, 28) java: 内部类lab.Outer.Inner中的静态声明非法 修饰符 'static' 仅允许在常量变量声明中使用Error:(21, 22) java: 内部类lab.Outer.Inner中的静态声明非法 修饰符 'static' 仅允许在常量变量声明中使用Error:(26, 34) java: 内部类lab.Outer.Inner中的静态声明非法 修饰符 'static' 仅允许在常量变量声明中使用Error:(31, 30) java: 内部类lab.Outer.Inner中的静态声明非法 修饰符 'static' 仅允许在常量变量声明中使用

从运行结果来看,我们不可以在非静态内部类中定义任何类变量(静态变量)。

8.内部类中的类方法

我们可以像定义普通类里面的成员一样来定义内部类里面的成员。

演示:

请创建一个外部类Outer,在外部类Outer里面创建一个内部类Inner。在内部类Inner中定义类方法。

请观察程序运行结果。

代码:

Outer类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

Main类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

结果:

“全栈2019”Java第六十七章:内部类、嵌套类详解

错误信息:

“全栈2019”Java第六十七章:内部类、嵌套类详解

文字版:

/Users/admin/Workspace/Java/Hello/src/lab/Outer.javaError:(26, 28) java: 内部类lab.Outer.Inner中的静态声明非法 修饰符 'static' 仅允许在常量变量声明中使用Error:(33, 22) java: 内部类lab.Outer.Inner中的静态声明非法 修饰符 'static' 仅允许在常量变量声明中使用Error:(40, 34) java: 内部类lab.Outer.Inner中的静态声明非法 修饰符 'static' 仅允许在常量变量声明中使用Error:(47, 30) java: 内部类lab.Outer.Inner中的静态声明非法 修饰符 'static' 仅允许在常量变量声明中使用

从运行结果来看,我们不可以在非静态内部类中定义任何类方法(静态方法)。

9.内部类中的静态常量

我们可以像定义普通类里面的成员一样来定义内部类里面的成员。

演示:

请创建一个外部类Outer,在外部类Outer里面创建一个内部类Inner。在内部类Inner中定义静态常量。

请观察程序运行结果。

代码:

Outer类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

Main类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

结果:

“全栈2019”Java第六十七章:内部类、嵌套类详解

我们可以在内部类Inner中定义和普通类一样的静态常量,可同时定义private,public,protected或package private四种访问权限的静态常量。在内部类Inner构造方法中我们访问了这些内部类静态常量,从运行结果来看,完全没有问题。同样的我们可不可以在外界创建内部类对象,然后访问内部类静态常量呢?来看看吧:

Outer类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

Main类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

结果:

“全栈2019”Java第六十七章:内部类、嵌套类详解

错误信息:

“全栈2019”Java第六十七章:内部类、嵌套类详解

文字版:

/Users/admin/Workspace/Java/Hello/src/main/Main.javaError:(11, 67) java: anInt 在 lab.Outer.Inner 中是 private 访问控制Error:(12, 71) java: aFloat在lab.Outer.Inner中不是公共的; 无法从外部程序包中对其进行访问Error:(13, 70) java: aDouble 在 lab.Outer.Inner 中是 protected 访问控制

从运行结果来看,我们不能从内部类对象直接访问定义在内部类里面的静态常量。接下来试试直接用内部类类名来访问:

Outer类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

Main类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

结果:

“全栈2019”Java第六十七章:内部类、嵌套类详解

错误信息:

“全栈2019”Java第六十七章:内部类、嵌套类详解

文字版:

/Users/admin/Workspace/Java/Hello/src/main/Main.java

Error:(11, 70) java: anInt 在 lab.Outer.Inner 中是 private 访问控制

Error:(12, 74) java: aFloat在lab.Outer.Inner中不是公共的; 无法从外部程序包中对其进行访问

Error:(13, 73) java: aDouble 在 lab.Outer.Inner 中是 protected 访问控制

从错误信息来看,只有公共的静态常量可以被访问。其他三个访问类型不行,来试试public。Outer类无需修改,只需修改Main类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

结果:

“全栈2019”Java第六十七章:内部类、嵌套类详解

从运行结果来看,我们可以通过内部类类名访问内部类中公开的静态常量。

10.内部类中的静态最终方法

我们可以像定义普通类里面的成员一样来定义内部类里面的成员。

演示:

请创建一个外部类Outer,在外部类Outer里面创建一个内部类Inner。在内部类Inner中定义静态最终方法。

请观察程序运行结果。

代码:

Outer类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

Main类:

“全栈2019”Java第六十七章:内部类、嵌套类详解

结果:

“全栈2019”Java第六十七章:内部类、嵌套类详解

错误信息:

“全栈2019”Java第六十七章:内部类、嵌套类详解

文章版:

/Users/admin/Workspace/Java/Hello/src/lab/Outer.java

Error:(26, 34) java: 内部类lab.Outer.Inner中的静态声明非法

修饰符 'static' 仅允许在常量变量声明中使用

Error:(33, 28) java: 内部类lab.Outer.Inner中的静态声明非法

修饰符 'static' 仅允许在常量变量声明中使用

Error:(40, 40) java: 内部类lab.Outer.Inner中的静态声明非法

修饰符 'static' 仅允许在常量变量声明中使用

Error:(47, 36) java: 内部类lab.Outer.Inner中的静态声明非法

修饰符 'static' 仅允许在常量变量声明中使用

从运行结果来看,我们不可以在非静态内部类中定义任何静态最终方法(静态最终方法)。

总结

  • 在Java中,我们可以在一个类中再定义一个类,这样称之为内部类。
  • 内部类又称之为嵌套类。
  • 内部类分为两类:静态和非静态。 声明为static的内部类称为静态内部类。 非静态内部类称为内部类。
  • 要实例化内部类,必须首先实例化外部类。
  • 内部类中的实例变量。可以通过内部类内部访问,外界内部类对象只能访问public修饰的。
  • 内部类中的实例方法。可以通过内部类内部访问,外界内部类对象只能访问public修饰的。
  • 内部类中的常量。可以通过内部类内部访问,外界内部类对象只能访问public修饰的。
  • 内部类中的最终方法。可以通过内部类内部访问,外界内部类对象只能访问public修饰的。
  • 内部类中的类变量。内部类不可以定义任何类变量。
  • 内部类中的类方法。内部类不可以定义任何类方法。
  • 内部类中的静态常量。可以通过内部类内部访问,外界内部类对象只能访问public修饰的。
  • 内部类中的静态最终方法。内部类不可以定义任何静态最终方法。

至此,Java中内部类、嵌套类相关内容讲解先告一段落,更多内容请持续关注。

答疑

如果大家有问题或想了解更多前沿技术,请在下方留言或评论,我会为大家解答。

上一章

“全栈2019”Java第六十六章:抽象类与接口详细对比

下一章

“全栈2019”Java第六十八章:外部类访问内部类成员详解

学习小组

加入同步学习小组,共同交流与进步。

  • 方式一:关注头条号Gorhaf,私信“Java学习小组”。
  • 方式二:关注公众号Gorhaf,回复“Java学习小组”。

全栈工程师学习计划

关注我们,加入“全栈工程师学习计划”。

“全栈2019”Java第六十七章:内部类、嵌套类详解

版权声明

原创不易,未经允许不得转载!