文章目录

  • 简介
  • 内部类
    • 静态内部类
    • 非静态内部类
    • 静态方法内部类
    • 非静态方法的内部类
    • 匿名类
  • 内部接口
  • 总结


简介

一般来说,我们创建类和接口的时候都是一个类一个文件,一个接口一个文件,但有时候为了方便或者某些特殊的原因,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(){@Overridepublic int compare(Object o1, Object o2) {return 0;}});SortedSet sortedSet2 = new ConcurrentSkipListSet((o1, o2) -> 0);}}

内部接口

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

public interface Map<K, V> {interface Entry<K, V> {K getKey();}

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

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

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

总结

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

本文的例子https://github.com/ddean2009/learn-java-base-9-to-20

©著作权归作者所有:来自51CTO博客作者ddean2009的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. java中Comparable和Comparator的区别
  2. spring-data详解之spring-data-jpa:简单三步快速上手spring-data-
  3. spring-boot+mybatis开发实战:如何在spring-boot中使用myabtis持
  4. eNSP:实现不同网段不同vlan主机之间的互访(配置三层交换)
  5. eNSP:访问控制列表 ACL
  6. eNSP:hybrid接口配置实例
  7. macvlan Multus-CNI在OpenShift上的使用
  8. (unix domain socket)使用udp发送>=128K的消息会报ENOBUFS的错误
  9. 怎么评价欧盟统一充电接口?

随机推荐

  1. PHP用于解析JSON并添加到数据库mysql
  2. 通过PHP设置html属性的最佳做法是什么?
  3. 以编程方式编写CSS背景的最佳方法?
  4. 安装nginx并配置php环境
  5. 在Yii中获取当前控制器和操作ID
  6. 基于PHP聊天室的编程思想
  7. 检查PHP是否启用了JavaScript
  8. php计算几分钟前、几小时前、几天前的几
  9. jQuery ajax调用不会调用我的php页面
  10. 复制到剪贴板没有瑞士法郎。只使用javasc