内部类详解
内部类
内部类的作用
每个内部类都能独立地继承来自一个(接口的)实现,所以无论外部类是否继承了某个(接口的)实现,对于内部类都没有影响,如果没有内部类提供的可以继承多个具体或抽象的类的能力,一些设计与编程问题就很难解决,从这个角度看,内部类使得多重继承的解决方案变得完整,接口解决了部分问题,而内部类有效的实现了"多重继承"
成员
成员内部类,静态内部类
局部
方法内部类、匿名内部类
依赖外部类对象的, 成员内部类,方法内部列,匿名内部类
静态内部类不依赖外部类的对象,所以,我们在项目中优先考虑选择静态内部类(不会产生内存泄漏)
问题: 局部内部类访问局部变量必须用final修饰,为什么?
当调用这个方法时,局部变量如果没有用final修饰,它的生命周期和方法的生命周期是一样的,当方法被调用时会入栈,方法结束后即弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有马上消失想用这个局部变量,显然已经无法使用了,如果用final修饰会在类加载的时候进入常量池,即方法弹栈,常量池的常量还在,也就可以继续使用了。(在jdk1.8中取消了这个特性)
关于内部类的代码整理:
package com.lili.innerClass;
/**
* 内部类:
* 1.成员内部类:直接定义在方法内部的类
* 2.方法内部类:在一个类的方法中定义一个类
* (1)方法内部类只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化
* (2)方法内部类对象不能使用该内部类所在方法的非final局部变量
* 3.静态内部类:在一个类内部定义一个静态内部类
* (1)静态的含义是该内部类可以像其他静态成员一样,没有外部类对象时,也能够访问它,静态嵌套类仅能访问外部类的静态成员方法
* 4.匿名内部类就是没有名字的内部类
* 匿名内部类的三种情况:
* (1) 继承式的匿名内部类
* (2) 接口式的匿名内部类
* (3) 参数式的匿名内部列
*
* @author: QiJingJing
* @create: 2021/7/4
*/
public class Test1 {
public static void main(String[] args) {
Outer outer = new Outer();
// Outer.Inner inner = outer.new Inner();
// inner.show(); 影响美观,不建议使用
outer.innerShow();
outer.showClass();
Outer.Inner2 inner2 = new Outer.Inner2();
inner2.show();
// 抽象类式
outer.print1();
// 接口式
outer.print2();
// 参数式
outer.print3(() -> System.out.println("我是参数式匿名内部类"));
}
}
class Outer {
private String name;
// 建议在外部类中定义一个方法,对外提供访问内部类的接口
public void innerShow() {
Inner inner = new Inner();
inner.show();
}
// 成员内部类
private class Inner {
public void show() {
System.out.println("我是成员内部类");
}
}
// -------------方法内部类---------
// show方法的参数或局部变量,实际必须是常量final
public void showClass() {
int x = 10;
// 在一个方法中定义一个类
class Inner1 {
public void show() {
// x++; 从内部类引用的本地变量必须是最终变量或实际上的最终变量
System.out.println("我是方法内部类" + x);
}
}
Inner1 inner1 = new Inner1();
inner1.show();
}
// -----------静态内部类---------
static class Inner2 {
public void show() {
System.out.println("我是静态内部类");
}
}
// ------------匿名内部类-------
// 抽象式匿名内部类
public void print1() {
new Dog() {
@Override
void run() {
System.out.println("小狗会跑");
}
}.run();
}
// 接口式匿名内部类
public void print2() {
new Person() {
@Override
public void eat() {
System.out.println("人会吃");
}
}.eat();
}
// 参数式匿名内部类
public void print3(Person person) {
person.eat();
}
}
/**
* 定义一个抽象类
*/
abstract class Dog {
abstract void run();
}
/**
* 定义一个接口
*/
interface Person {
void eat();
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!