java中的内部类内部接口详解

简介: java中的内部类内部接口详解

目录



简介


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


内部类


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


静态内部类


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


@Slf4j
public 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中定义的类也可以是非静态的,如下所示:


@Slf4j
public 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的。我们看下面的例子:


@Slf4j
public 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();
    }
}


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


非静态方法的内部类


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


@Slf4j
public 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<K, V> {
    interface Entry<K, V> {
        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个内部类的实现和一个内部接口的应用。大家只要把内部的类或者接口看成一个变量,就可以很好的理解上面的内容了。


相关文章
|
2天前
|
存储 Java
java IO接口(Input)用法
【5月更文挑战第1天】Java的`java.io`包包含多种输入输出类。此示例展示了如何使用`FileInputStream`从`input.txt`读取数据。首先创建`FileInputStream`对象,接着创建一个字节数组存储读取的数据,调用`read()`方法将文件内容填充至数组。然后将字节数组转换为字符串并打印,最后关闭输入流。注意,`InputStream`是抽象类,此处使用其子类`FileInputStream`。其他子类如`ByteArrayInputStream`、`ObjectInputStream`和`BufferedInputStream`各有特定用途。
9 2
|
2天前
|
NoSQL Java API
java一行代码实现RESTFul接口
Spring Data REST是构建在Spring Data之上的库,可自动将repository转换为REST服务,支持JPA、MongoDB、Neo4j、GemFire和Cassandra。无需手动创建Service和Controller层。要开始,需配置JPA数据源,创建实体类和Repository接口。快速实现REST接口,只需引入spring-boot-starter-data-rest Maven依赖,并在Repository接口上添加@RepositoryRestResource注解。
|
3天前
|
Java 程序员 数据格式
关于Java抽象类和接口的总结和一点个人的看法
关于Java抽象类和接口的总结和一点个人的看法
|
8天前
|
存储 安全 Java
[Java基础面试题] Map 接口相关
[Java基础面试题] Map 接口相关
|
9天前
|
Java
一文搞清楚Java中的包、类、接口
包、类、接口、方法、变量、参数、代码块,这些都是构成Java程序的核心部分,即便最简单的一段代码里都至少要包含里面的三四个内容,这两天花点时间梳理了一下,理解又深刻了几分。
31 10
|
14天前
|
Java 开发者
探索 Java 的函数式接口和 Lambda 表达式
【4月更文挑战第19天】Java 中的函数式接口和 Lambda 表达式提供了简洁、灵活的编程方式。函数式接口有且仅有一个抽象方法,用于与 Lambda(一种匿名函数语法)配合,简化代码并增强可读性。Lambda 表达式的优点在于其简洁性和灵活性,常用于事件处理、过滤和排序等场景。使用时注意兼容性和变量作用域,它们能提高代码效率和可维护性。
|
14天前
|
Java
Java接口中可以定义哪些方法?
【4月更文挑战第13天】
14 0
Java接口中可以定义哪些方法?
|
14天前
|
Java API
什么是Java函数式接口?
【4月更文挑战第13天】
15 0
什么是Java函数式接口?
|
16天前
|
设计模式 Java
Java接口与抽象类
Java接口与抽象类
17 0
|
20天前
|
安全 Java 编译器
接口之美,内部之妙:深入解析Java的接口与内部类
接口之美,内部之妙:深入解析Java的接口与内部类
38 0
接口之美,内部之妙:深入解析Java的接口与内部类