内部类详解

内部类

内部类的作用

每个内部类都能独立地继承来自一个(接口的)实现,所以无论外部类是否继承了某个(接口的)实现,对于内部类都没有影响,如果没有内部类提供的可以继承多个具体或抽象的类的能力,一些设计与编程问题就很难解决,从这个角度看,内部类使得多重继承的解决方案变得完整,接口解决了部分问题,而内部类有效的实现了"多重继承"

成员

成员内部类,静态内部类

局部

方法内部类、匿名内部类

依赖外部类对象的, 成员内部类,方法内部列,匿名内部类

静态内部类不依赖外部类的对象,所以,我们在项目中优先考虑选择静态内部类(不会产生内存泄漏)

问题: 局部内部类访问局部变量必须用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();
}
posted @   JamieChyi  阅读(12)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示