什么是内部类?内部类有哪些?怎么使用?——内部类用法

365BET 2026-02-17 19:43:50 admin 6552 114
什么是内部类?内部类有哪些?怎么使用?——内部类用法

内部类

概念

定义在一个类内部的类叫做内部类

public class Demo3 {

}

class Outer{

//

class Inner{

}

}

特点

每一个类都会生成一个单独的字节码文件

分类

1、成员内部类

2、静态内部类

3、局部内部类

4、匿名内部类(最常用的一个内部类 也是jdk8中新特性Lambda的前提)

一、成员内部类

1、定义位置

外部类的成员位置

2、特点

特点:可以访问外部类的私有成员⽽不破环封装

案例:

public class Demo3 {

}

class Outer{

private int a = 10;

private void m(){

System.out.println("我是外部类中的私有成员方法");

}

private static void m2(){

System.out.println("我是外部类中的私有静态方法");

}

//成员位置

//成员内部类

class Inner {

public void m1(){

System.out.println(a);//可以直接访问外部类的私有成员而不破环封装

m();

m2();

}

}

}

3、对象的创建方式

1. 先创建外部类对象

2. 通过外部类对象创建内部类对象

案例

//案例1: 关于成员内部类对象的创建

package com.ujiuye.day13;

public class Demo3 {

public static void main(String[] args) {

//创建成员内部类对象

// 1 创建外部类对象

// Outer outer = new Outer();//有名对象

//new Outer();//匿名对象 只能使用一次

//

// //2 通过外部类的对象 创建内部类的对象

// // 类名 对象名 = new 类名();

// Outer.Inner inner = outer.new Inner();

//简写

Outer.Inner inner = new Outer().new Inner();

}

}

class Outer{

private int a = 10;

private void m(){

System.out.println("我是外部类中的私有成员方法");

}

private static void m2(){

System.out.println("我是外部类中的私有静态方法");

}

//成员位置

//成员内部类 ---> 地位 就相当于 成员变量 和 成员方法的地位 随着对象的创建而存在

class Inner {

public void m1(){

System.out.println(a);//可以直接访问外部类的私有成员而不破环封装

m();

m2();

}

}

}

创建对象方式:

//方式一

// 1 创建外部类对象

Outer outer = new Outer();//有名对象

// 2 通过外部类的对象 创建内部类的对象

// 类名 对象名 = new 类名();

Outer.Inner inner = outer.new Inner();

//方式二

//简写

Outer.Inner inner = new Outer().new Inner();

4、注意事项

1. 当内部类存在和外部类成员变量重名问题 通过 外部类.this 访问外部类的属性

this. 代表的是本类的引⽤

外部类.this. 代表的是外部类的引⽤

2. 不能在成员内部类中创建静态成员(因为 成员内部类的角色地位和成员变量是同等,也是随着外部类的对象创建而存在

但是如果有静态成员的话 内部类的类加载 先于外部类的类加载 ->矛盾

案例

//案例1: 关于注意事项1

public class Demo3 {

public static void main(String[] args) {

Outer.Inner inner = new Outer().new Inner();

//调用方法

inner.m1();

}

}

class Outer{

//外部类中成员变量 a

private int a = 10;

//成员内部类 ---> 地位 就相当于 成员变量 和 成员方法的地位 随着对象的创建而存在

class Inner {

//成员内部类中的成员变量

int a = 20;

public void m1(){

//成员内部类 中局部变量

int a = 30;

//访问每个a

System.out.println(a);//30

// 在内部类中 本质上有 两个this 内部类对象的this 外部类对象的引用this

System.out.println(this.a);//默认Inner.this

System.out.println(Inner.this.a);//20

System.out.println(Outer.this.a);//10

}

}

}

//案例2: 关于注意事项2

package com.ujiuye.day13;

public class Demo3 {

public static void main(String[] args) {

Outer.Inner inner = new Outer().new Inner();

//调用方法

inner.m1();

}

}

class Outer{

//外部类中成员变量 a

private int a = 10;

//成员内部类 ---> 地位 就相当于 成员变量 和 成员方法的地位 随着对象的创建而存在

class Inner {

//成员内部类中的成员变量

int a = 20;

//static int b = 10;//不可以

// public static void m2(){//不可以的

//

// }

public void m1(){

//成员内部类 中局部变量

int a = 30;

//访问每个a

System.out.println(a);//30

// 在内部类中 本质上有 两个this 内部类对象的this 外部类对象的引用this

System.out.println(this.a);//默认Inner.this

System.out.println(Inner.this.a);//20

System.out.println(Outer.this.a);//10

}

}

}

二、 静态内部类

1、位置

在外部类中,和静态成员并列 static 修饰的成员内部类

2、语法

static class 类名{

3、对象创建方式

语法:外部类类名.内部类类名 对象名 = new 外部类.内部类();

public class Demo3 {

public static void main(String[] args) {

//静态内部类的对象创建

// 静态成员 可以通过 类名.直接放完 静态内部类 也可以通过 外部类. 访问内部类的类名

// 静态内部类 什么时候进行初始化? 静态内部类 随着 外部类 类加载的的进行而存在

// 没有必要创建外部类对象 直接通过类名.创建对象

// 类名 对象名 = new 类名(); Outer.Inner 看成一个整体

Outer.Inner inner = new Outer.Inner();

}

}

//外部类

class Outer{

//静态内部类

static class Inner{

}

}

4、特点

静态内部类中不能直接访问外部类⾮静态的成员

案例

//案例1:

public class Demo3 {

public static void main(String[] args) {

//静态内部类的对象创建

// 静态成员 可以通过 类名.直接放完 静态内部类 也可以通过 外部类. 访问内部类的类名

// 静态内部类 什么时候进行初始化? 静态内部类 随着 外部类 类加载的的进行而存在

// 没有必要创建外部类对象 直接通过类名.创建对象

// 类名 对象名 = new 类名(); Outer.Inner 看成一个整体

Outer.Inner inner = new Outer.Inner();

}

}

//外部类

class Outer {

//外部类的属性

int a = 10;//外部类的成员变量

static int b = 20;//外部类的静态变量

//外部类的成员方法

public void m1() {

System.out.println("我是外部类的成员方法");

}

//外部类的静态方法

public static void m2() {

System.out.println("我是外部类的静态方法");

}

//静态内部类

static class Inner {

//定义一个内部类的成员方法

public void m3() {

// System.out.println(a);//a是非静态属性

// m1();//m1方法是非静态方法

//非要访问 外部类的成员变量 和调用成员方法

// 创建外部类的对象

// Outer outer = new Outer();

// System.out.println(outer.a);

// outer.m1();

// System.out.println(b);

// m2();

}

}

}

//案例2:

public class Demo3 {

public static void main(String[] args) {

//静态内部类的对象创建

// 静态成员 可以通过 类名.直接放完 静态内部类 也可以通过 外部类. 访问内部类的类名

// 静态内部类 什么时候进行初始化? 静态内部类 随着 外部类 类加载的的进行而存在

// 没有必要创建外部类对象 直接通过类名.创建对象

// 类名 对象名 = new 类名(); Outer.Inner 看成一个整体

Outer.Inner inner = new Outer.Inner();

}

}

//外部类

class Outer {

//外部类的属性

int a = 10;//外部类的成员变量

static int b = 20;//外部类的静态变量

//外部类的成员方法

public void m1() {

System.out.println("我是外部类的成员方法");

}

//外部类的静态方法

public static void m2() {

System.out.println("我是外部类的静态方法");

}

//静态内部类

static class Inner {

int a = 10;

static int b = 20;

//定义一个内部类的静态方法

public static void m3() {

System.out.println(a);

System.out.println(b);

}

}

}

//案例3: 关于重名问题

public class Demo3 {

public static void main(String[] args) {

//静态内部类的对象创建

// 静态成员 可以通过 类名.直接放完 静态内部类 也可以通过 外部类. 访问内部类的类名

// 静态内部类 什么时候进行初始化? 静态内部类 随着 外部类 类加载的的进行而存在

// 没有必要创建外部类对象 直接通过类名.创建对象

// 类名 对象名 = new 类名(); Outer.Inner 看成一个整体

Outer.Inner inner = new Outer.Inner();

inner.m();

}

}

//外部类

class Outer {

static int b = 20;//外部类的静态变量

//静态内部类

static class Inner {

static int b = 30;

public void m(){

System.out.println(b);//30

System.out.println(this.b);

System.out.println(Inner.b);

System.out.println(Outer.b);

}

}

}

三、 局部内部类(重点)

1、位置

在外部类的⽅法中定义局部内部类, 局部位置 ---> 和 局部变量属于一个等级

2、语法

//定义外部类

class Outer{

public void m1() {

//定义局部内部类

class Inner{

}

}

}

3、创建对象方式

局部内部类的对象只能在它所在的⽅法中 定义内部类语句之后创建

//案例:

public class Demo3 {

public static void main(String[] args) {

}

}

//外部类

class Outer {

//外部类的成员方法

public void m(){

//局部位置

//局部内部类 ---> 随着 方法的压栈而初始化

// 局部内部类的 作用域 从定义行开始 到所在的最近的代码块结束

class Inner{

}

//在定义局部内部类之后 才能创建对象

Inner inner = new Inner();

}

}

4、特点

1.在局部内部类中可以访问外部类中的成员,局部内部类中不可以定义静态成员

2.局部内部类访问外部类的局部变量 要求这个局部变量必须是final修饰的 在jdk7中必须加final

jdk8可以不加但是默认是final

//案例:

package com.ujiuye.day13;

public class Demo3 {

public static void main(String[] args) {

}

}

//外部类

class Outer {

int a = 10;

static int b = 20;

public void m1(){

System.out.println("我是外部类的成员方法");

}

public static void m2(){

System.out.println("我是外部类的静态方法");

}

//外部类的成员方法

public void m(){

//局部位置

//局部内部类 ---> 随着 方法的压栈而初始化

// 局部内部类的 作用域 从定义行开始 到所在的最近的代码块结束

class Inner{

public void m3(){

System.out.println(a);

System.out.println(b);

m1();

m2();

}

}

}

}

//案例2: 关于特点2

public class Demo3 {

public static void main(String[] args) {

Outer outer = new Outer();

outer.m();

}

}

//外部类

class Outer {

int a = 10;//外部类的成员变量

//外部类的成员方法

public void m(){

int a = 20;//外部类的局部变量

class Inner{

public void m3(){

//用不到 外部类中的局部变量 ----> 就是没有加final

//用到 外部类中的局部变量 ---> 系统在jdk8之后 会默认加fianl 在jdk7之前 需要手动加final才能访问

System.out.println(a);//局部内部类可以访问外部类的局部变量

}

}

Inner inner = new Inner();

inner.m3();

}

}

案例3: 重名问题

public class Demo3 {

public static void main(String[] args) {

Outer outer = new Outer();

outer.m();

}

}

//外部类

class Outer {

int a = 10;//外部类的成员变量a

//外部类的成员方法

public int m(){

int a = 20;//外部类的局部变量a

class Inner{

int a = 30;//内部类的成员变量a

public void m3(){

int a = 40;//内部类的局部变量a

//System.out.println(a);//40

// System.out.println(this.a);//30

// System.out.println(Inner.this.a);//30

// System.out.println(Outer.this.a);//10

// int a = 20; 这个a没法访问

// Outer outer = new Outer();

// int m = outer.m();

// System.out.println(m);

}

}

Inner inner = new Inner();

inner.m3();

return a;

}

}

四、匿名内部类

1、概念

匿名内部类是非静态内部类的一种特殊情况,匿名内部类没有类名。优点: 可以让程序员专注于代码逻辑的实现,让编程的思路更加的顺利.

2、要求

必须继承一个类 或者 实现一个接口 ----> 这个类要想写成匿名内部类的形式 必须要求 有亲爹 或者有一个干爹

3、特点

一个匿名内部类只能创建一个对象

案例

import java.util.Scanner;

public class Demo5 {

public static void main(String[] args) {

// 1 可以直接通过学校获取老师

Scanner scanner = new Scanner(System.in);

System.out.println("请输入你的学号:");

int code = scanner.nextInt();

Teacher teacher = School.getTeacher(code);

//老师上课

teacher.teach();

//2 老师现在不受学校的监管 -----> 违法 学校不允许

// Liu liu = new Liu();

// liu.teach();

//3 学生还可以 通过去学校里 找到刘老师教Java 但是没有经过选课系统

// School.Liu liu = new School.Liu();

//

// liu.teach();

// 4站在学生的角度分析

// 对于学生 来说:

}

}

//定义一个学校类

class School{

//功能 根据学号分配老师

public static Teacher getTeacher(int code){

if (code%2 == 0){

//返回了一个 Teacher 接口的实现类对象 只不过这个类没有名字

return new Teacher(){//类没有名字了 但是告诉系统 我是谁得儿子

@Override

public void teach() {

System.out.println("教Java");

}

};

}else{

return new Teacher(){

@Override

public void teach() {

System.out.println("教前端");

}

};

}

}

}

//接口

interface Teacher{

//规则

void teach();

}

五、内部类的字节码文件名的总结

不管是外部类 还是 内部类 经过编译最终都会形成一个单独的字节码文件,字节码文件名和外部类类名有联系

1、成员内部类

内部类的字节码文件名: 外部类类名$内部类类名.class

2、静态内部类

内部类的字节码文件名: 外部类类名$内部类类名.class

3、局部内部类

内部类字节码文件名: 外部类类名$序号内部类类名.class 序号: 从 1开始的

4、匿名内部类

内部类字节码文件名: 外部类类名$序号.class 序号从 1开始编号

相关推荐

365365bet官网 银雕游戏鼠标测评怎么样

银雕游戏鼠标测评怎么样

📅 08-16 👁️ 8981
足球365官网是哪个 instax mini 25- 产品介绍

instax mini 25- 产品介绍

📅 06-27 👁️ 3152
足球365官网是哪个 青鱼与草鱼美味大比拼,揭秘哪种鱼类更胜一筹

青鱼与草鱼美味大比拼,揭秘哪种鱼类更胜一筹

📅 07-25 👁️ 2751