我的编程空间,编程开发者的网络收藏夹
学习永远不晚

解析JavaSe的内部类

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

解析JavaSe的内部类

内部类

1. 内部类简介

(1) 内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。

(2) 内部类成员可以直接访问外部类的私有数据,因为内部类被当成其外部类成员,同一个类的成员之间可以互相访问。但外部类不能访问内部类的实现细节,例如内部类的成员变量。

(3) 匿名内部类适合用于创建那些仅需要一次使用的类。

(4) 在java中内部类主要分为成员内部类(非静态内部类、静态内部类)、匿名内部类、局部内部类。

2. 非静态内部类

成员内部类是一种与Field、方法、构造器和初始化块相似的类成员,成员内部类分为两种:静态内部类和非静态内部类,使用static修饰的成员内部类是静态内部类,没有使用static修饰的成员内部类是非静态内部类。

  • 因为内部类作为其外部类的成员,所以可以使用任意访问控制符如private、protected和public等修饰;
  • 非静态内部类不能有静态方法、静态属性、静态初始化块;
  • 非静态内部类可以直接访问外部类的成员,但是外部类不能直接访问非静态内部类成员;
  • 外部类的静态方法、静态代码块中不能直接创建非静态内部类实例,访问内部类成员;
  • 非静态内部类的对象必须寄存在外部类的对象里,因此创建非静态内部类对象之前,必须先创建其外部类对象;

当在非静态内部类的方法内访问某个变量时,系统优先在该方法内查找是否存在该名字的局部变量,如果存在就使用该变量;如果不存在,则到该方法所在的内部类中查找是否存在该名字的成员变量,如果存在则使用该成员变量;如果不存在,则到该内部类所在的外部类中查找是否存在该名字的成员变量,如果存在则使用该成员变量;如果依然不存在,系统将出现编译错误:提示找不到该变量。

(1) 非静态内部类可以直接访问外部类的成员,但是外部类不能直接访问非静态内部类成员

public class OuterClass {
    private int a;
    public void test(){
        // 编译报错,因为外部类不能直接访问非静态内部类成员
        System.out.println(b);
        // 如需访问内部类的实例Field,需显式创建内部类对象
        InnerClass inner = new InnerClass();
        System.out.println(inner.b);
    }
    // 定义非静态内部类,使用private修饰符
    @Data
    private class InnerClass{
        private int b;
        public void info(){
            // 在非静态内部类里可以直接访问外部类的private成员
            System.out.println(a);
        }
    }
}

(2) 非静态内部类不能有静态方法、静态属性、静态初始化块

public class OuterClass {
    // 外部类Field
    private int a;
    // 定义非静态内部类,使用private修饰符
    @Data
    private class InnerClass{
        // 内部类Field
        private int b;
        private int c;
        // 编译报错,非静态内部类里面不能有静态属性
        private static int d;
        // 编译报错,非静态内部类里面不能有静态代码块
        static {
            System.out.println("非静态内部类里面不能有静态代码块");
        }
        // 编译报错,非静态内部类里面不能有静态方法
        public static void show(){
            System.out.println("非静态内部类里面不能有静态方法");
        }
    }
}

(3) 外部类的静态方法、静态代码块中不能直接创建非静态内部类实例,访问内部类成员

public class OuterClass {
    private int a;
    public static void test(){
        // 编译报错,外部类的静态方法中无法创建内部类实例
        InnerClass innerClass = new InnerClass();
    }
    static{
        // 编译报错,外部类的静态方法中无法创建内部类实例
        InnerClass innerClass = new InnerClass();
    }
    // 定义非静态内部类
    @Data
    private class InnerClass{
        private int b;
    }
}

在外部类的普通方法和静态方法中访问内部类成员

public class OuterClass {
    private int a;
    // 定义非静态内部类,使用private修饰符
    @Data
    private class InnerClass{
        private int b;
        public void info(){
            System.out.println("内部类的方法info()");
        }
    }
    // 外部类的代码块
    {
        InnerClass innerClass = new InnerClass();
        innerClass.info();
    }
    // 外部类的静态代码块
    static {
        OuterClass.InnerClass inner = new OuterClass().new InnerClass();
        inner.info();
    }
    // 外部类的普通方法
    public void test(){
        // 在外部类里使用非静态内部类时,与平时使用普通类并没有太大的区别
        InnerClass inner = new InnerClass();
        // 访问内部类的Filed
        System.out.println(inner.b);
        // 访问内部类的方法
        inner.info();
    }
    //  外部类的静态方法
    public static void test1(){
        // 外部类的静态方法、静态代码块中不能直接创建非静态内部类实例
        OuterClass.InnerClass inner = new OuterClass().new InnerClass();
        // 访问内部类的Filed
        System.out.println(inner.b);
        // 访问内部类的方法
        inner.info();
    }
    // 测试
    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        outerClass.test();
    }
}

3. 静态内部类

如果使用static来修饰一个内部类,则这个内部类就属于外部类本身,而不属于外部类的某个对象。static关键字的作用是把类的成员变成类相关,而不是实例相关,即static修饰的成员属于整个类,而不属于单个对象。

  • 静态内部类可以包含静态成员,也可以包含非静态成员。
  • 静态内部类不能访问外部类的实例成员,只能访问外部类的类成员;
  • 外部类不能直接访问静态内部类的成员,但可以使用静态内部类的类名作为调用者来访问静态内部类的类成员,也可以使用静态内部类对象作为调用者来访问静态内部类的实例成员。

(1) 静态内部类不能访问外部类的实例成员,只能访问外部类的类成员

public class OuterClass {
    private int a;
    private static int b;
    public void test(){
        System.out.println(a);
    }
    @Data
    private static class InnerClass{
        private int c;
        // 静态内部类中可以包括静态成员
        private static int d;
        public void info(){
            // 编译报错,静态内部类不能访问外部类的实例成员
            System.out.println(a);
        }
        public static void show(){
            // 静态内部类可以访问外部类的静态成员
            System.out.println(b);
        }
    }
}

(2) 外部类不能直接访问静态内部类的成员,但可以使用静态内部类的类名作为调用者来访问静态内部类的类成员,也可以使用静态内部类对象作为调用者来访问静态内部类的实例成员。

public class OuterClass {
    private int a;
    private static int b;
    public void test(){
        // 外部类不能直接访问静态内部类的成员
        // 可以使用静态内部类对象作为调用者来访问静态内部类的实例成员
        InnerClass innerClass = new InnerClass();
        innerClass.show();
        // 可以使用静态内部类的类名作为调用者来访问静态内部类的类成员
        InnerClass.show();
    }
    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        outerClass.test();
    }
    @Data
    private static class InnerClass{
        private int c;
        private static int d;
        public static void show(){
            System.out.println(b);
        }
    }
}

4. 匿名内部类

匿名内部类适合创建那种只需要一次使用的类,创建匿名内部类时会立即创建一个该类的实例,这个类定义立即消失,匿名内部类不能重复使用。

  • 匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类,或实现一个接口;
  • 匿名内部类不能是抽象类,因为系统在创建匿名内部类时,会立即创建匿名内部类的对象。因此不允许将匿名内部类定义成抽象类;
  • 匿名内部类不能定义构造器,因为匿名内部类没有类名,所以无法定义构造器,但匿名内部类可以定义实例初始化块,通过实例初始化块来完成构造器需要完成的事情;
public interface Product {
     public int getPrice();
     public String getName();
}
public class Test {
    public void test(Product product){
        System.out.println("name:"+product.getName() +"-------"+"name:"+product.getPrice());
    }
    public static void main(String[] args) {
        Test test = new Test();
        test.test(new Product() {
            @Override
            public int getPrice() {
                return 12;
            }
            @Override
            public String getName() {
                return "苹果";
            }
        });
    }
}

Test类定义了一个test方法,该方法需要一个Product对象作为参数,但Product只是一个接口,无法直接创建对象,因此此处考虑创建一个Product接口实现类的对象传入该方法——如果这个Product接口实现类需要重复使用,则应该将该实现类定义成一个独立类;如果这个Product接口实现类只需一次使用,则可采用上面程序中的方式,定义一个匿名内部类。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!   

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

解析JavaSe的内部类

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

JavaSE中内部类及常用API有哪些

这篇文章将为大家详细讲解有关JavaSE中内部类及常用API有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1.内部类1.1 内部类概述内部类:就是在一个类中定义一个类。例如:在一个类A内部定义一个类
2023-06-22

如何理解Java内部类中的局部内部类

这篇文章给大家介绍如何理解Java内部类中的局部内部类,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。局部内部类  局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或
2023-06-05

如何理解Java内部类中的匿名内部类

如何理解Java内部类中的匿名内部类,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。匿名内部类  匿名内部类应该是平时我们编写代码时用得最多的,在编写事件监听的代码时使用匿名
2023-06-05

如何理解Java内部类中的成员内部类

如何理解Java内部类中的成员内部类,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的
2023-06-05

Java的内部类实例分析

这篇文章主要介绍了Java的内部类实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java的内部类实例分析文章都会有所收获,下面我们一起来看看吧。内部类:其实内部类顾名思义,就是类中类,一个类里面还有一个
2023-06-29

Java内部类示例分析

这篇文章主要介绍“Java内部类示例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java内部类示例分析”文章能帮助大家解决问题。1.内部类概念及分类将一个类定义在另一个类的内部或者接口内部或者
2023-06-29

浅析Java语言中的内部类

浅析Java语言中的内部类[@more@]  提起Java内部类(Inner Class)可能很多人不太熟悉,实际上类似的概念在C++里也有,那就是嵌套类(Nested Class),关于这两者的区别与联系,在下文中会有对比。内部类从表面上
2023-06-03

Java内部类和异常类的示例分析

这篇文章将为大家详细讲解有关Java内部类和异常类的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1 内部类Java支持在一个类中声明另一个类,这样的类称作内部类,而包含内部类的类成为内部类的外嵌
2023-06-14

java外部类与内部类怎么理解

本篇内容主要讲解“java外部类与内部类怎么理解”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“java外部类与内部类怎么理解”吧! 一、内部类内部类就是将一个类A定义在类B里边,里边的那个类A称
2023-06-22

java内部测试类的示例分析

这篇文章将为大家详细讲解有关java内部测试类的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。我们一般使用的java内部类有4种形式:一般内部类、局部内部类、匿名内部类、静态内部类。以下是我作的一
2023-05-30

java 内部类的实例详解

java 内部类的实例详解可以将一个类的定义放在另一个类的定义内部,这就是内部类。内部类是一个非常有用的特性但又比较难理解使用的特性(鄙人到现在都没有怎么使用过内部类,对内部类也只是略知一二)。第一次见面内部类我们从外面看是非常容易理解的,
2023-05-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录