
java 内部类 局部内部类 匿名内部类 成员内部类 静态内部类
发布日期:2021-05-07 10:30:28
浏览次数:13
分类:原创文章
本文共 9175 字,大约阅读时间需要 30 分钟。
- 基本介绍
一个类的内部又完整的嵌套了另一个类结构.被嵌套的类称为内部类(inner class),嵌套其它类的类称为外部类(outher class),内部类最大的特点是可以直接访问私有属性,并且可以体现类与类之间的包含关系// 外部类class Outer{ // 内部类 class Inner{ }}// 其它类/外部其它类class Other{ }
内部类分类
- 定义在外部类局部位置上(比如方法内):
- 局部内部类(有类名)
- 匿名内部类(没有类名)
- 定义在外部类的成员位置上:
- 成员内部类(没有static修饰)
- 静态内部类(使用static修饰)
局部内部类
- 局部内部类是定义在外部类的局部位置,比如方法中,并且有类名.
- 可以直接访问外部类的所有成员,包含私有的
- 不能添加访问修饰符,因为它的地位就是一个局部变量,但是可以使用final修饰,因为局部变量也可以使用final
- 作用域:仅仅在定义它的方法或代码块中
public class LocalInnerClass { public static void main(String[] args) { Outer02 outer02 = new Outer02(); outer02.m1(); }}/** * 外部类 */class Outer02 { private int n1 = 100; private void m2(){ System.out.println("Outer02 m2()"); } /** * 方法 */ public void m1() { /** * 1.局部内部类是定义在外部类的局部位置,通常在方法内 * 3.不能添加访问修饰符,但是可以使用final修饰,加final就不能被继承 * 4.作用域: 仅仅在定义它的方法或代码块中 */ class Inner02 { //局部内部类 /** * 2.可以直接访问外部类的所有成员, 包含私有的 */ private int n1 = 800; public void f1(){ //5.局部内部类可以直接访问外部类的成员, 比如 n1 m2() //6.如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员 //使用外部类名.this.成员去访问 //Outher02.this 本质就是外部类的对象,即哪个对象调用了m1(),Outher.this就是那个对象 System.out.println("n1= " + n1 + " 外部类的n1=" + Outher02.this.n1); m2(); } } //6.外部类在方法中,可以创建Inner01对象,然后调用方法即可 Inner02 inner02 = new Inner02(); inner02.f1(); } { class Inner03{ } }}// 输出n1= 100Outer02 m2()
匿名内部类
- 本质是类
- 内部类
- 该类没有名字
- 匿名内部类是定义在外部类的局部位置, 比如方法中,并且没有类名
基本语法:
new 类或接口(参数列表){ 类体 };
public class Anonymous { public static void main(String[] args) { new Outher04().method(); }}class Outher04{ //外部类 /** * 属性 */ private int n1 = 10; /** * 方法 */ public void method() { // 基于接口的匿名内部类 // 需求: 想使用IA接口,并创建对象 // 传统方式: 写一个类,实现该接口,并创建对象 // 如果(Tiger/Dog)类只是使用了一次 => new Tiger().cry(); // 可以使用匿名内部类来简化开发 /** * 编译类型: IA * 运行类型: 匿名内部类 Outher04$1 * 底层会分配类名 Outher04$1 * class Outher04$1 implements IA { * @Override * public void cry() { * System.out.println("老虎叫唤"); * } * } */ // jdk底层创建匿名内部类Outher04$1,并且立即创建了Outher04$1实例,并且把地址返回给tiger IA tiger = new IA() { @Override public void cry() { System.out.println("老虎叫唤"); } }; // tiger的运行类型: class com.ll.demo.innerclass.Outher04$1 System.out.println("tiger的运行类型: " + tiger.getClass()); // 老虎叫唤 tiger.cry(); //================================================== // 基于类的匿名内部类 // father编译类型: Father // father运行类型: Outher04$2 // 底层会创建匿名内部类,同时返回匿名内部类Outher04$2的对象 /* * class Outher04$2 extends Father { * @Override public void test() { System.out.println("匿名内部类重写了test方法"); } * } * */ // 参数列表"jack"会传递给构造器 Father father = new Father("jack"){ @Override public void test() { System.out.println("匿名内部类重写了test方法"); } }; // father的运行类型: class com.ll.demo.innerclass.Outher04$2 System.out.println("father的运行类型: " + father.getClass()); // 匿名内部类重写了test方法 father.test(); //================================================== //基于抽象类的匿名内部类 Animal animal = new Animal(){ @Override void eat() { System.out.println("吃东西"); } }; // class com.ll.demo.innerclass.Outher04$3 System.out.println("animal的运行类型: " + animal.getClass()); // 吃东西 animal.eat(); }}/** * 接口 */interface IA { void cry();}/** * 传统方式 */class Tiger implements IA { @Override public void cry() { System.out.println("老虎叫"); }}class Dog implements IA { @Override public void cry() { System.out.println("狗叫"); }}class Father { private String name; public Father(String name){ this.name = name; } public void test() { }}/** * 抽象类 */abstract class Animal { abstract void eat(); public void test() { }}
细节
public class AnonymousInnerClassDetail { public static void main(String[] args) { Outer05 outer05 = new Outer05(); outer05.f1(); // 1798286609 System.out.println(outer05.hashCode()); }}class Outer05 { private int n1 = 99; public void f1() { // 创建一个基于类的匿名内部类 // 不能添加访问修饰符,因为它的地位就是一个局部变量 // 作用域: 仅仅在定义它的方法或代码块中 // 匿名内部可以直接访问外部类 Person person = new Person() { private int n1 = 23; @Override public void hi() { // 可以直接访问外部类的所有成员,包含私有的 // 如果外部类和匿名内部类的成员重名时,匿名内部类访问的话 // 默认遵循就近原则,如果想访问外部类的成员,则使用(外部类名.this.成员)去访问 // 匿名内部类重写了hi方法, n1:23, 访问外部类的n1:99 System.out.println("匿名内部类重写了hi方法, n1:" + n1 + ", 访问外部类的n1:" + Outer05.this.n1); // Outer05.this 就是调用f1的对象 // 1798286609 System.out.println(Outer05.this.hashCode()); } }; //动态绑定,会执行重写后的方法,运行类型是Outer05$1 person.hi(); //也可以直接调用,匿名内部类本身也是返回对象 // class 匿名匿名内部类 extends Person{} new Person() { @Override public void hi() { System.out.println("哈哈哈"); } @Override public void ok(String str) { System.out.println("ok" + str); } }.ok("123"); }}/** * 父类 */class Person { public void hi() { System.out.println("Person hi()"); } public void ok(String str) { System.out.println("Person ok()" + str); }}// 抽象类/接口...
public class InnerClassExercise01 { public static void main(String[] args) { f1(new AA() { @Override public void show() { System.out.println("这是一幅名画"); } }); new AA() { @Override public void show() { System.out.println("这是一幅名画"); } }.show(); } /** * 静态方法, 形参是接口类型 * @param aa */ public static void f1(AA aa) { aa.show(); }}/** * 接口 */interface AA { void show();}
public class InnerClassExercise02 { public static void main(String[] args) { CellPhone cellPhone = new CellPhone(); cellPhone.alarmclock(new Bell() { @Override public void ring() { System.out.println("手机闹钟"); } }); cellPhone.alarmclock(new Bell() { @Override public void ring() { System.out.println("小伙伴们上课了"); } }); new Bell(){ @Override public void ring() { System.out.println("测试"); } }.ring(); }}interface Bell { void ring();}class CellPhone{ public void alarmclock(Bell bell) { bell.ring(); }}
成员内部类
- 成员内部类是定义在外部类的成员位置,并且没有static修饰
- 可以直接访问外部类的所有成员,包含私有的
- 可以添加任意访问修饰符(public,protected,默认,private),因为它的地址就是一个成员
public class MemberInnerClass01 { public static void main(String[] args) { Outer.Inner08 inner08 = new Outer().new Inner08(); // 10,张三 inner08.say(); // 10,张三 new Outer().test(); }}/** * 外部类 */class Outer { private int n1 = 10; public String name = "张三"; /** * 成员内部类 */ class Inner08 { public void say() { System.out.println(n1 + "," + name); } } public void test() { Inner08 inner08 = new Inner08(); inner08.say(); }}
成员内部类练习
public class Homework07 { public static void main(String[] args) { Car car = new Car(-1); car.getAir().flow(); new Car(60).new Air().flow(); }}class Car { private double temperature; public Car(double temperature) { this.temperature = temperature; } class Air { public void flow() { if (temperature > 40) { System.out.println("冷气"); } else if(temperature < 0) { System.out.println("暖气"); } else { System.out.println("关闭空调"); } } } public Air getAir() { return new Air(); }}// 输出暖气冷气
静态内部类
- 静态内部类是定义在外部类的成员位置,并且有static修饰
- 可以直接访问外部类的所有静态成员,包含私有的,但是不能访问非静态成员
- 可以添加任意访问修饰符(public,protected,默认,private)
- 作用域: 同其它的成员一样
public class StaticInnerClass01 { public static void main(String[] args) { Outer10.Inner10 inner10 = new Outer10.Inner10(); inner10.test(); }}/** * 外部类 */class Outer10 { private int n1 = 10; private static String name = "张三"; /** * 静态内部类 */ static class Inner10 { public void test() { System.out.println(name); } }}
发表评论
最新留言
留言是一种美德,欢迎回访!
[***.207.175.100]2025年04月09日 03时36分33秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
【数算-31】【十大常用算法-03】动态规划算法与背包问题
2019-03-04
【SE-02】多线程-02
2019-03-04
$set的使用(视图不能实时更新)
2019-03-04
Spring知识小汇(6)——Bean的自动装配
2019-03-04
一、硬件防火墙
2019-03-04
Javaweb jQuery功能练习
2019-03-04
余生,愿你能靠近那些正能量的人——
2019-03-04
初学QT
2019-03-04
IOC容器_Bean管理xml方式
2019-03-04
蓝桥杯入门练习题斐波那契数列
2019-03-04
(Java基础类库 )System类
2019-03-04
context:include-filter与exclude-filte控制扫描组件
2019-03-04
【SSL】1072砝码称重
2019-03-04
js数据结构--队列--常见操作
2019-03-04
JS数据结构--单向链表--常见操作
2019-03-04
【SSL】1606&【洛谷】P2014选课
2019-03-04
JS数据结构--双向链表--常见操作
2019-03-04
c++的内存管理
2019-03-04
全排列(深度优先搜索+递归)
2019-03-04
多项式插值法的Python程序
2019-03-04