您现在的位置是:首页 > 编程 > 

Java内部类详解

2025-07-24 03:42:27
Java内部类详解 一、简介1、概述:一个事物的内部包含另一个事物,那就是一个类的内部包含另一个类;例如:身体内部包含心脏,汽车内部包含发动机;内部类必须在内部类之内。2、分类成员内部类;局部内部类(包含匿名内部类);二、使用1、成员内部类定义格式:代码语言:javascript代码运行次数:0运行复制修饰符 class 内部类名称{ 修饰符 class 内部类名称{

Java内部类详解

一、简介

1、概述:

一个事物的内部包含另一个事物,那就是一个类的内部包含另一个类;

例如:身体内部包含心脏,汽车内部包含发动机;

内部类必须在内部类之内。

2、分类

成员内部类;

局部内部类(包含匿名内部类);

二、使用

1、成员内部类

定义格式:
代码语言:javascript代码运行次数:0运行复制
修饰符 class 内部类名称{

    修饰符 class 内部类名称{

        //……

    }

    //……

}
注意:

内用外,可以随意访问;外用内,需要借助内部类对象;

代码示例:
代码语言:javascript代码运行次数:0运行复制
public class Body {//外部类
    public String name = "小明";
    public class Heart{//内部类
        //内部类的属性
        public String title = "心脏";
        //内部类方法
        public void beat(){
            println("心脏跳动……");
            //下面这样写在实际运行时会报错,所以只作为解释所用
            //内部类可以随意调用外部类的属性和方法
            //println(name);
            //sport();
        }
    }
    //外部类方法
    public void sport(){
        println("身体运动……");
        //外部类必须通过内部类对象调用其属性和方法
        Heart heart = new Heart();
        println();
        heart.beat();
    }
}
如何使用成员内部类:

①间接方式:通过外部类方法内创建内部类对象间接访问内部类;

②直接方式:创建内部类——外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();

Test测试类:
代码语言:javascript代码运行次数:0运行复制
public class Test {
    public static void main(String[] args) {
        //间接方式
        Body body = new Body();
        body.sport();
        //身体运动……
        //心脏
        //心脏跳动……
        //直接方式
        Body.Heart heart = new Body().new Heart();
        heart.beat();//心脏跳动……
    }
}

2、内部类同名变量的访问

代码语言:javascript代码运行次数:0运行复制
public class Outer {
    private int a = 10;
    public class Inner{
        private int a = 20;
        public void getInt(){
            int a = 0;
            println(a);//0,局部变量就近原则
            println(this.a);//20,内部类的成员变量
            println(a);//10,外部类的成员变量
        }
    }
}

、局部内部类

含义:

一个类定义在一个方法内。

只有当前方法可以使用它,出了这个方法就无法使用了。

代码演示:

定义:
代码语言:javascript代码运行次数:0运行复制
public class Outer {
    private int a = 10;
    public void getInt(){
        class Inner{
            public void getInt(){
                println(a);//10
            }
        }
        //使用的时候只能通过间接调用该方法进行类的使用
        Inner inner = new Inner();
        inner.getInt();
    }
}
使用:
代码语言:javascript代码运行次数:0运行复制
public class Test {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.getInt();//10
    }
}
局部内部类的final问题:

局部内部类访问所在方法的局部变量,那么这个局部变量必须是“有效”final的(可以不给变量加final(省略),但不可更改,加上final更好);

局部内部类访问外部类成员变量、局部变量、内部类成员变量,以及内部类成员方法中修改内部类成员变量:

Outer:

代码语言:javascript代码运行次数:0运行复制
public class Outer {
    private int a = 10;
    public void getInt(){
        int a = 20;
//      a = 60;//错误写法,此处的a是常量,只是省略了final
        class Inner{
//          private int a = 0;//若没有内部类的该成员变量0,则访问的是局部变量20
            private void getInt(){
//              a = 40;//【正确写法】若没有在此处改变,则访问内部类的该成员变量值是0
                println(a);//20,局部不变,就近原则
                println(a);//10,外部类成员变量
            }
        }
        //使用的时候只能通过间接调用该方法进行类的使用
        Inner inner = new Inner();
        inner.getInt();
    }
}

Test测试类:

代码语言:javascript代码运行次数:0运行复制
public class Test {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.getInt();//20 10
    }
}

4、匿名内部类【重要】

概述:

如何接口的实现类或者父类的子类只需要使用一次,此时就适合使用匿名内部类;

定义格式:

接口名称 对象名 = new 接口名称(){

//重写所有的抽象方法

}

代码演示:

接口:

代码语言:javascript代码运行次数:0运行复制
public interface MyInterface {
    void speak();
}

Test测试类:

代码语言:javascript代码运行次数:0运行复制
public class Test01 {
    public static void main(String[] args) {
        MyInterface myInterface = new MyInterface() {
            @Override
            public void speak() {
                println("匿名内部类");
            }
        };
        myInterface.speak();//匿名内部类
        //下面是java8的lambda表达式,效果一样
//        MyInterface myInterface = () -> println("匿名内部类");
//        myInterface.speak();
    }
}
注意事项:

格式解析:

new 接口名称(){...}

①new代表创建对象的动作;

②接口名称指的是实现的是那个接口;

③{...}是匿名内部类的内容;

注意的问题:

①匿名内部类在【创建对象】的时候只能唯一使用一次;

②匿名对象在【调用方法】的时候只能调用一次;

③匿名内部类是省略了【实现类/子类名称】,但是匿名对象是省略了【对象名称】;

5、类作为成员变量类型

学生类:
代码语言:javascript代码运行次数:0运行复制
public class Student {
    private String name;

    public Student() {
    }

    public Student(String name) {
         = name;
    }

    public String getame() {
        return name;
    }

    public void setame(String name) {
         = name;
    }
}
班级类:
代码语言:javascript代码运行次数:0运行复制
public class ClassRoom {
    private String name;
    private Student student;

    public ClassRoom() {
    }

    public ClassRoom(String name, Student student) {
         = name;
        this.student = student;
    }

    public String getame() {
        return name;
    }

    public void setame(String name) {
         = name;
    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }
}
Test测试类:
代码语言:javascript代码运行次数:0运行复制
public class Test02 {
    public static void main(String[] args) {
        ClassRoom classRoom = new ClassRoom("1班",new Student("小明"));
        println(classRoom.getame());//1班
        println(classRoom.getStudent().getame());//小明
    }
}

6、接口作为成员变量类型

传入接口参数的三个方法:

①使用实现类,传入实现类的对象;

②使用匿名内部类,传入对象名;

③使用匿名内部类和匿名对象,全部传入参数;

代码:

接口:

代码语言:javascript代码运行次数:0运行复制
public interface Ability {
    void study();
}

接口实现类:

代码语言:javascript代码运行次数:0运行复制
public class AbilityImpl implements Ability {
    @Override
    public void study() {
        println("接口实现类的study");
    }
}

实体类:

代码语言:javascript代码运行次数:0运行复制
public class Student {
    private String name;
    private Ability ability;

    public Student() {
    }

    public Student(String name,Ability ability) {
         = name;
        this.ability = ability;
    }

    public String getame() {
        return name;
    }

    public void setame(String name) {
         = name;
    }

    public Ability getAbility() {
        return ability;
    }

    public void setAbility(Ability ability) {
        this.ability = ability;
    }

}

Test测试类:

代码语言:javascript代码运行次数:0运行复制
public class Test01 {
    public static void main(String[] args) {
        Student student = new Student();
        student.setame("小明");
        AbilityImpl ability = new AbilityImpl();
        student.setAbility(ability);//接口实现类的study 通过接口的实现类传入参数
        Ability ability1 = new Ability() {
            @Override
            public void study() {
                println("接口匿名内部类的study");
            }
        };
        student.setAbility(ability1);//接口匿名内部类的study 通过匿名内部类传入参数
        student.setAbility(new Ability() {
            @Override
            public void study() {
                println("接口匿名内部类匿名对象的study");
            }
        });//接口匿名内部类匿名对象的study 通过匿名内部类的匿名对象传入参数
    }
}

7、接口作为方法的参数和返回值

代码语言:javascript代码运行次数:0运行复制
public class Test0 {
    public static void main(String[] args) {
        //List是一个接口
        List<String> list = new ArrayList<>();
        List<String> result = addames(list);
        for (String string : result) {
            println(string);
//            小黑
//            小白
//            小红
//            小兰
//            小俊
        }
    }
    private static List<String> addames(List<String> list){
        list.add("小黑");
        list.add("小白");
        list.add("小红");
        list.add("小兰");
        list.add("小俊");
        return list;
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2025-01-06,如有侵权请联系 cloudcommunity@tencent 删除变量对象接口javapublic

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1200614.html

相关标签:无
上传时间: 2025-07-23 19:29:08
留言与评论(共有 7 条评论)
本站网友 联合幕墙论坛
21分钟前 发表
匿名内部类【重要】概述:如何接口的实现类或者父类的子类只需要使用一次
本站网友 孟加拉豹猫
21分钟前 发表
局部内部类含义:一个类定义在一个方法内
本站网友 20074
8分钟前 发表
汽车内部包含发动机;内部类必须在内部类之内
本站网友 绣眉技术
21分钟前 发表
如有侵权请联系 cloudcommunity@tencent 删除前往查看变量对象接口javapublic
本站网友 vray材质库
24分钟前 发表
那就是一个类的内部包含另一个类;例如:身体内部包含心脏
本站网友 两岸三地
27分钟前 发表
那么这个局部变量必须是“有效”final的(可以不给变量加final(省略)