简介

一般来说,我们创建类和接口的时候都是一个类一个文件,一个接口一个文件,但有时候为了方便或者某些特殊的原因,java并不介意在一个文件中写多个类和多个接口,这就有了我们今天要讲的内部类和内部接口。

内部类

先讲内部类,内部类就是在类中定义的类。类中的类可以看做是类的一个属性,一个属性可以是static也可以是非static的。而内部类也可以定义在类的方法中,再加上匿名类,总共有5种内部类。

静态内部类

我们在class内部定义一个static的class,如下所示:

@Slf4jpublic class StaticInnerClass {    static class Inner {        void print() {            log.info("Inner class is: " + this);        }    }    public static void main(String[] args) {        StaticInnerClass.Inner inner = new StaticInnerClass.Inner();        inner.print();    }}

因为static变量可以直接根据类名来存取,所以我们使用new StaticInnerClass.Inner()来实例化内部类。

非静态内部类

class中定义的类也可以是非静态的,如下所示:

@Slf4jpublic class InnerClass {     class Inner {        void print() {            log.info("Inner class is: " + this);        }    }    public static void main(String[] args) {        InnerClass.Inner inner = new InnerClass().new Inner();        inner.print();    }}

要访问到类的变量,需要实例化外部内,然后再实例化内部类:new InnerClass().new Inner()。

注意这里我们需要使用到两个new。

静态方法内部类

我们可以在静态方法中定义一个类,这个类其实就相当于方法中的变量,这个变量当然不能是static的。我们看下面的例子:

@Slf4jpublic class StaticMethodInnerClass {    private static String x = "static x";    public static void print() {        class MyInner {            public void printOuter() {                log.info("x is " + x);            }        }        MyInner i = new MyInner();        i.printOuter();    }    public static void main(String[] args) {        StaticMethodInnerClass.print();    }}

方法中的类,我们是无法在外部实例化的。

非静态方法的内部类

同样的非静态方法也可以定义内部类:

@Slf4jpublic class MethodInnerClass {    private  String x = "non static x";    public  void print() {        class MyInner {            public void printOuter() {                log.info("x is " + x);            }        }        MyInner i = new MyInner();        i.printOuter();    }    public static void main(String[] args) {        new MethodInnerClass().print();    }}

注意,这里需要先实例化外部类才可以继续调用。

匿名类

最后一个,匿名类,直接在需要的时候实例化的类。匿名类我们遇到了很多次了,比如在构建SortedSet的时候,可以传入自定义的Comparator,我们可以用匿名类来实现,也可以直接使用lambda表达式。

public class AnonymousClass {    public static void main(String[] args) {        SortedSet sortedSet1 = new ConcurrentSkipListSet(new Comparator(){            @Override            public int compare(Object o1, Object o2) {                return 0;            }        });        SortedSet sortedSet2 = new ConcurrentSkipListSet((o1, o2) -> 0);    }}

内部接口

Inner Interface是指在接口中定义的接口。最常见的就是Map中的Entry了:

public interface Map {    interface Entry {        K getKey();    }

这里的内部接口一定是static的,因为接口是不能实例化的,所以为了访问到接口中的接口,必须定义为static。如果不指定,则默认就是static。

我们看一个该内部接口的实现:

public class MapImpl implements Map.Entry{    @Override    public Object getKey() {        return 0;    }    @Override    public Object getValue() {        return null;    }    @Override    public Object setValue(Object value) {        return null;    }}

总结

本文讲解了5个内部类的实现和一个内部接口的应用。大家只要把内部的类或者接口看成一个变量,就可以很好的理解上面的内容了。

本文作者:flydean程序那些事

本文来源:flydean的博客

欢迎关注我的公众号:程序那些事,更多精彩等着您!

软件外部接口和内部接口_java中的内部类内部接口详解相关推荐

  1. java中迭代器要导包吗_java 中迭代器的使用方法详解

    java 中迭代器的使用方法详解 前言: 迭代器模式将一个集合给封装起来,主要是为用户提供了一种遍历其内部元素的方式.迭代器模式有两个优点:①提供给用户一个遍历的方式,而没有暴露其内部实现细节:②把元 ...

  2. java 静态 编译_Java中的动态和静态编译实例详解

    Java中的动态和静态编译实例详解 首先,我们来说说动态和静态编译的问题. Q: java和javascript有什么区别? 总结了一下:有以下几点吧: 1.首先从运行环境来说java代码是在JVM上 ...

  3. java mod %区别_Java中 % 与Math.floorMod() 区别详解

    %为取余(rem),Math.floorMod()为取模(mod) 取余取模有什么区别呢? 对于整型数a,b来说,取模运算或者取余运算的方法都是: 1.求 整数商: c = a/b; 2.计算模或者余 ...

  4. java中math的方法_Java中Math类常用方法代码详解

    近期用到四舍五入想到以前整理了一点,就顺便重新整理好经常见到的一些四舍五入,后续遇到常用也会直接在这篇文章更新... public class Demo{ public static void mai ...

  5. java foreach标签_Java中Velocity foreach循环标签详解

    Java中Velocity foreach循环标签详解 Java Velocity中foreach循环可以很容易的遍历数组或者集合. 定义 #foreach( $elem in $allElems) ...

  6. 实现了某一个接口的匿名类的例子_java中的内部类内部接口详解,一文搞定

    简介 一般来说,我们创建类和接口的时候都是一个类一个文件,一个接口一个文件,但有时候为了方便或者某些特殊的原因,java并不介意在一个文件中写多个类和多个接口,这就有了我们今天要讲的内部类和内部接口. ...

  7. java中抽象类 接口_java中的抽象类与接口

    1.抽象类的定义 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类. 2.简单实例 ...

  8. java中如何定义接口_java中如何定义一个接口

    使用interface来定义一个接口.接口定义同类的定义类似,也是分为接口的声明和接口体,其中接口体由常量定义和方法定义两部分组成.定义接口的基本格式如下:[修饰符] interface 接口名 [e ...

  9. java implements 多个接口_JAVA中implements实现多接口

    JAVA中implements实现多接口 这里有一个游戏,人猿泰山. 主角是一个单独的类,这里我们主要用怪物说明接口的用法: 怪物有很多种, 按地域分:有的在天上飞,有的在地上跑,有的在水里游 按攻击 ...

最新文章

  1. 北斗产业发展现状与前景预测研究
  2. 解决yum安装报错Protected multilib versions
  3. 如何自学python数据分析-Python学习干货 |如何用Python进行数据分析?
  4. Class.forName解析以及使用
  5. HTML5 input元素新的特性
  6. boost::mp11::mp_transform相关用法的测试程序
  7. 【英语学习】【Daily English】U10 Education L03 She's planning to study abroad
  8. 【ElasticSearch】Es 源码之 ClusterService 源码解读
  9. ElasticSearch7.2只能用localhost访问但不能用IP地址访问---ElasticSearch工作笔记027
  10. python资料-Python 有哪些好的学习资料或者博客?
  11. ssh配置config文件,实现vscode免密登陆
  12. html 字体围绕图片效果
  13. 会php学java入门要多久_php自学需要多久
  14. Type-C边充电边OTG芯片LDR6028A
  15. 迷宫问题寻宝(c++实现,求最短路径,显示路径)
  16. Kafka分区副本重分配源码分析
  17. Chrome 超强生产力工具 Omni
  18. RationalDMIS 7.1 程序示例
  19. SECS半导体设备通讯-1 SECS的基本概念
  20. 未名企鹅极客 | 医药流向的数据仓库建模

热门文章

  1. MySQL基础篇(01):经典实用查询案例,总结整理
  2. 歪枣网Mysql优化总结
  3. 上传大文件:在 System.Web.HttpRequest.GetEntireRawContent()
  4. 作为Java工程师,你的Spring用对了吗?
  5. 单元测试:unittest.TestCase
  6. mybatis源码解析(五) --- typehandler注册和处理的查询结果对象的类型转换
  7. 在windows命令行中查询MySQL乱码
  8. FAQ系列 | 几种常见MySQL无法启动案例
  9. [C++基础]037_编写不可被继承的类
  10. OJ1074: 百钱买百鸡(C语言)