java中的内部类

article/2025/10/12 1:12:59

java中的内部类主要分为两类四种:

第一类:定义在外部类局部位置上,分为局部内部类( 有 类名)、匿名内部类(没有类名)。

第二类:定义在外部类的成员位置上,分为成员内部类(没有static修饰)、静态内部类(使用static修饰)。

一:局部内部类

局部内部类是定义在外部类的局部位置,比如方法中,并且有类名。

局部内部类的使用

1.局部内部类可以直接访问外部类的所有成员,包含私有的,访问方式——直接访问。

2.不能添加访问修饰符,因为它的地位就是一个局部变量,局部变量是不能使用修饰符的。但是可以使用final修饰,因为局部变量也可以使用final。

3.作用域仅仅在定义它的方法或代码块中

4.外部类访问局部内部类,访问方式:创建对象,在访问(注意:必须在作用域内)

对上面的使用以代码的形式呈现:

public class TestDemo {public static void main(String[] args) {Person person = new Person();person.method2();}
}
class Person{//外部类private String name = "张三";private int age = 20;private void method1(){System.out.println("外部类中的method1方法");}public void method2(){final class Student{//局部内部类可以加fianl关键字private String name = "王五";public void method3(){method1();//可以访问外部类中的成员}}/*** 外部类访问局部内部类的方式:创建对象再访问*/Student student = new Student();student.method3();}
}

 

5.外部其他类不能直接访问局部内部类(因为局部内部类是一个局部变量) 

6.如果外部类和局部内部类的成员重名时,默认遵循就近访问原则,如果打破原则访问外部类成员,则可以使用(外部类名.this.成员)去访问。

代码演示上面两个使用:

public class TestDemo {public static void main(String[] args) {Person person = new Person();person.method2();//不能直接访问局部内部类//person.student;//报错:Cannot resolve symbol 'student'}
}
class Person{//外部类private String name = "张三";private int age = 20;private void method1(){System.out.println("外部类中的method1方法");}public void method2(){final class Student{//局部内部类可以加fianl关键字private String name = "王五";public void method3(){System.out.println(name);//遵循就近原则System.out.println(Person.this.name);//同名时访问外部成员method1();//可以访问外部类中的成员}}/*** 外部类访问局部内部类的方式:创建对象再访问*/Student student = new Student();student.method3();}
}

 

二:匿名内部类 

上面四种内部类中只需要掌握这一种即可,这是以后代码中经常会用到的,很重要。

匿名内部类的定义

匿名内部类是没有名称的内部类。在Java中调用某个方法时,如果该方法的参数是接口类型,除了可以传接口实现类外,还可以使用实现接口的匿名内部类作为参数,在匿名内部类中直接完成方法的实现。

通过一段代码来解释匿名内部类:

public class TestDemo02 {public static void main(String[] args) {People people = new People();people.method();}
}
class People{private String name;public void method(){class Student implements behavior{@Overridepublic void eat() {System.out.println("学生韩梅梅正在吃饭");}}Student student = new Student();student.eat();class Teacher implements behavior{@Overridepublic void eat() {System.out.println("老师李华正在吃饭");}}Teacher teacher = new Teacher();teacher.eat();}
}
interface behavior{public void eat();
}

 

从上面可以看到People类里面有两个内部类Student、Teacher,两个类都实现了behavior接口并实现了里面吃这个行为。 

细心的朋友已经观察到了,上面的代码不是局部内部类吗,和匿名内部类与啥关系。在这里我们通过局部内部类主要是为了引出匿名内部类。观察上面的代码,发现为了调用内部类里面的方法,就必须实例化对象,然后在调用。如果内部类一多,比如现在有Father、Marther.......众多的内部类,难道都要一个个实例吗,为了简化开发,java开发者就创建了匿名内部类,看下面的代码。

public class TestDemo02 {public static void main(String[] args) {People people = new People();people.method();}
}
class People{private String name;public void method(){Behavior student = new Behavior() {@Overridepublic void eat() {System.out.println("学生韩梅梅正在吃饭");}};student.eat();Behavior teacher = new Behavior() {@Overridepublic void eat() {System.out.println("老师李华正在吃饭");}};teacher.eat();}
}
interface Behavior{public void eat();
}

上面的代码就是利用匿名内部类实现多对象的创建,合理使用匿名内部类可以很大程度简化代码量。

为看懂上面的代码,现在作如下分析:

1.分析上面student的编译类型和运行类型,编译类型为Behavior,运行类型正是匿名内部类。可能有的人会很以为,这个匿名内部类在哪里,怎么没看见。所谓匿名内部类,就是没有名字的类,也不能说没有名字吧,jdk底层给这个类分配了一个名字,就叫做People$1,只不过不显示出来,看如下代码就知道了:

public class TestDemo02 {public static void main(String[] args) {People people = new People();people.method();}
}
class People{private String name;public void method(){Behavior student = new Behavior() {@Overridepublic void eat() {System.out.println("学生韩梅梅正在吃饭");}};student.eat();System.out.println(student.getClass());//获取全路径类名}
}
interface Behavior{public void eat();
}

 

2.jdk底层创建完匿名内部类以后马上就实力化了该类的对象,也就是说底层一共做了两步动作,第一是创建匿名内部类,第二步是实力化对象。

3.上面的匿名内部类的操作步骤和局部内部类是一样的,只不过简化了代码而已。 

匿名内部类的语法

new 接口或类(参数列表){类体;
};

 下面在演示其他两种不同的匿名内部类:

一:基于类的匿名内部类

public class TestDemo02 {public static void main(String[] args) {new People("张三").method();}
}
class People{private String name;public People(String name) {this.name = name;}public void method(){Father father = new Father("张三"){@Overridepublic void sleep() {System.out.println("匿名内部类中的sleep方法");}};father.sleep();}
}
class Father{private String name;public Father(String name){this.name = name;}public void sleep(){System.out.println("正在睡觉");}
}

上面的匿名内部类是继承至Father这个类的,当匿名内部类调用sleep方法的时候,根据继承机制他首先在本类中找,刚好本类中有一个sleep方法,他就会执行本类中的方法,结果如下:

这里需要重点提一下:有得朋友可能会想,既然匿名内部类也是一个类,那么在类里面写一些方法,然后实力化调用这些方法是不是也行。这里需要指出,匿名内部类里面确实可以写自己的方法,但是不能调用,因为根据继承机制(实现接口也相当于继承,因为接口是一种特殊的类),匿名内部类作为一个子类,他是无法调用自身特有的方法的。这里也不能强转,因为你根本就不知道匿名内部类的运行类型是啥。所以综上,匿名内部类里面只能重写父类中的方法,然后调用。 

二:基于抽象类的匿名内部类

public class TestDemo02 {public static void main(String[] args) {People people = new People();people.method();}
}
class People{private String name;public void method(){Animal dog = new Animal() {@Overridevoid eat() {System.out.println("小狗吃东西");}};dog.eat();}
}
abstract class Animal{abstract void eat();
}

 

匿名内部类的使用

1.匿名内部类既是一个类,又是一个对象,既有定义类的特征,又有创建对象的特征。所以可以调用匿名内部类中的方法。

匿名内部类的使用和局部内部类一样,除了第四条。

 

 匿名内部类的使用场景

 一:当做实参直接传递

public class TestDemo02 {public static void main(String[] args) {show(new Peopel() {@Overridepublic void dance() {System.out.println("全名制作人们大家好,我是练习时长两年半的个人练习生蔡徐坤");}});}public static void show(Peopel peopel){peopel.dance();}
}
interface Peopel{public void dance();
}

 

二:在多态中的应用

public class TestDemo02 {public static void main(String[] args) {Ikun ikun = new Ikun();ikun.show(new Peopel() {@Overridepublic void dance() {System.out.println("你们都是黑子,只有我才是真爱粉");}});ikun.show(new Peopel() {@Overridepublic void dance() {System.out.println("会唱、跳、rap的才是ikun");}});}
}
class Ikun{public void show(Peopel peopel){peopel.dance();//这里会发生动态绑定}
}
interface Peopel{public void dance();
}

 

 

三:成员内部类

成员内部类的概念 

成员内部类是定义在外部类的成员位置上,并且没有static修饰

成员内部类的使用 

1.可以直接访问外部类的所有成员,包括私有的。外部类访问成员内部类访问方式:创建对象,再访问;

2.可以添加任意访问修饰符,因为它的地位就是一个成员;

3.作用域和外部类的其他成员一样,为整个类体

4.如果外部类和内部类的成员重名时,内部类访问的话,遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问。

5.外部其他类访问成员内部类有三种方式:第一种实例化外部类,然后访问;第二种将内部类作为外部类的成员实例化然后访问;第三种在外部类里面编写一个方法,可以返回内部类对象。

下面用代码演示上面的使用:

public class TestDemo02 {public static void main(String[] args) {People people = new People();people.method();//访问的第一种方式实例化外部类,通过外部类里面的方法访问//People.Student student = people.new Student();//访问的第二种方式,将内部类作为外部类的成员实例化然后访问/*** 访问的第三种方式* People.Student getStudent = people.getStudent();* getStudent.say();*/}
}
class People{//外部类private String name = "张三";private int age = 20;private void hi(){System.out.println("打招呼");}public class Student{//内部类private String name = "李四";private int age = 21;public void say(){System.out.println("name="+name+" age="+People.this.age);}}//返回Student类public Student getStudent(){return new Student();}public void method(){//外部类访问内部类Student student = new Student();student.say();}
}

 

 

四:静态内部类 

静态内部类的概念 

静态内部类是定义在外部类的成员位置上,并且有static修饰

静态内部类的使用

1.可以直接访问外部内的所有静态成员,包含私有的,但不能直接访问非静态的成员 

2.可以添加任意访问修饰符,因为它的地位就是一个成员;

3.作用域和外部类的其他成员一样,为整个类体

4.如果外部类和内部类的成员重名时,内部类访问的话,遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问。

这些都不重要就不演示了。


http://chatgpt.dhexx.cn/article/nj1SxheK.shtml

相关文章

java内部类最全详解

1、成员内部类 内部类与外部类的关系 a.成员内部类的创建需要依赖于外部类对象-(成员方法必须通过对象调用),在没有外部类实例之前无法创建成员内部类对象 b.内部类与外部类相对独立,不是is a 的关系(发动机-汽车&am…

Java内部类详解(含:成员内部类、局部内部类、匿名内部类、静态内部类)

内部类是什么? 字面意思,在类的内部编写的类就叫内部类!即一个类的内部又完整的嵌套了另一个类结构,被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class)。 内部类是类的第五大成员→【提示:类的五大成员…

分享15款很棒的 JavaScript 开发工具javascript

在开发中,借助得力的工具可以事半功倍。今天,这篇文章向大家分享最新收集的15款非常有用的 javascript 开发工具。 testswarm: continious & distributed js testing testswarm是mozilla实验室推出的一个开源项目,它旨在为开发者提供在多个浏览器版本上快速轻松测试自己j…

27 个面向开发人员的最佳 Vue.js 开发工具

英文 | https://javascript.plainenglish.io/best-27-vuejs-development-tools-for-developers-bd972bb5f573 01、BootstrapVue 地址:https://bootstrap-vue.org/ 一个用于 Vue.js 构建引导接口的开源库。 02、Vuex 地址:https://vuex.vuejs.org/ Vue.js…

15 款非常有用的 JavaScript 开发工具

开发者有个趁手的工具将事半功倍。今天这篇文章分享给大家最新的15款非常有用的JavaScript 开发工具。 列表如下: TestSwarm: Continious & Distributed JS Testing TestSwarm提供分布式的JavaScript持续集成测试。最初它的创造者John Resig只是将它作为…

03【WebStorm开发工具】

上一篇:02【HTML快速入门】 下一篇:04【】 目录:【HTML5系列教程】 文章目录 三、WebStorm开发工具3.1 WebStorm简介3.2 WebStorm安装3.3 WebStorm基本使用3.3.1 创建项目3.3.2 调整字体大小3.3.3 代码自动补全3.3.4 WebStorm常用快捷键 三…

web开发者工具 js

作为Web开发人员,我为什么喜欢Google Chrome浏览器 【原文地址:http://www.cnblogs.com/QLeelulu/archive/2011/08/28/2156402.html 】 在Google Chrome浏览器出来之前,我一直使用FireFox,因为FireFox的插件非常丰富,更…

JavaScript 专用开发工具

下载地址:http://soooh.com/3/jsedit.rar javaScript专用编辑工具,免费绿色版,需要.net2.0才能运行。 特色:左侧能列出javascript的函数列表,适合修改很大的js文件。

顶级 Vue.js 开发工具

Vue.js已成为当前最热门的JavaScript前端框架。Vue 是构建有用应用程序和网站的完美选择,无论你是经验丰富的开发人员,正希望切换到 Vue 上,还是刚刚开始工作的新人——选择正确的工具都是非常重要的。在合适的工具帮助下,你就能快…

JavaScript开发工具大全

译文:https://blog.fundebug.com/2017/06/19/javascript-tool-list/ 原文:https://da-14.com/blog/ultimate-list-javascript-tools \简介 2017年1月,Stack Overflow年度开发者调研一共访问了64000个程序员,发现JavaScript已经连续…

前端(HTML css JS)开发工具及常用插件推荐

前端编程工具有很多,例如Visual Studio Code(简称VS code),hbuilder,sublime text3,notepad,webstorm等等,今天给大家推荐的是VS code VS code是一个完全免费的软件,页面…

十款最新的JavaScript开发工具

JavaScript 自推出后就大受开发者的青睐,基于 JavaScript 的开发工具不计其数,开发者们可以灵活选择,轻松构建应用。本文分享了十款最新的 JavaScript 开发工具,喜欢的话就赶紧 mark! 1. Kreate 这款工具有助于对 jQu…

9个最好用的JavaScript开发工具和代码编辑器

Web设计和开发是现今越来越流行的职业方向之一。工欲善其事,必先利其器,如果你想在这个领域出类拔萃,那么你就必须具备一些优秀的技能,例如能操作不同的平台、IDE和其他各种各样的工具。 谈到平台和IDE,现在已经不是以…

js基础篇-开发工具

一. Javascript的开发工具主要包括浏览器和代码编辑器 浏览器:用于执行,调试js代码。 代码编辑器:用于编写代码。 1. 常见的浏览器 开发商浏览器特点MicrosoftInternet Explorerwindows操作系统的内置浏览器,用户数量较多Micros…

推荐15款很棒的 JavaScript 开发工具

在开发中,借助得力的工具可以事半功倍。今天这篇文章与大家分享最近发现的一些有用的 JavaScript 和 jQuery 的开发工具,库和插件。希望这些工具在你你即将到来的项目中能用得上。 01、TestSwarm: Continious & Distributed JS Testing 地址&#xf…

分享 27 个面向开发人员的最佳 Vue.js 开发工具

英文 | https://javascript.plainenglish.io/best-27-vuejs-development-tools-for-developers-bd972bb5f573 01、BootstrapVue 地址:https://bootstrap-vue.org/ 一个用于 Vue.js 构建引导接口的开源库。 02、Vuex 地址:https://vuex.vuejs.org/ Vue.js…

JS 开发工具库

JS 开发工具库 前言一、开发环境准备1、安装 Node2、创建项目 二、工具函数的封装1、Ajax 的封装2、datePicker3、文件导出功能的实现3-1 导出 Word 三、项目打包1、打包前准备1.1 初始化项目1.2 下载依赖1.3 配置 Webpack1.4 配置打包命令1.5 项目打包1.6 测试 2、暴露工具函数…

JavaScript 开发者的 5 款必备工具

工欲善其事,必先利其器,一款优秀的开发工具能够极大提高程序开发效率与体验。在Web前端开发中,常用的开发工具有Visual Studio Code、Sublime Text、HBuilder等,下面我们就来介绍这些开发工具的特点。 1.Visual Studio Code Vis…

学javascript需要用到哪些开发工具?分享这几款

学习web前端技术,辅助工具是在学习过程中必须要用到的,包括后面的工作中,辅助工具可以更快的提高我们的工作效率,下面小编就为大家整理了学javascript需要用到的开发工具。 学javascript有哪些开发工具: 1.HBuilder …

SQLLDR 简介

1. SQLLDR导入 1.1 简介 SQL*LOADER是ORACLE的数据加载工具,通常用来将操作系统文件(数据)迁移到ORACLE数据库中。SQL*LOADER是大型数据仓库选择使用的加载方法,因为它提供了最快速的途径(DIRECT,PARALLEL&…