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

Wesley13
• 阅读 461

简介

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

内部类

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

静态内部类

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

[@Slf4j](https://my.oschina.net/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](https://my.oschina.net/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](https://my.oschina.net/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](https://my.oschina.net/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](https://my.oschina.net/u/1162528)
            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个内部类的实现和一个内部接口的应用。大家只要把内部的类或者接口看成一个变量,就可以很好的理解上面的内容了。

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

本文作者:flydean程序那些事

本文链接:http://www.flydean.com/inner-class-inner-interface/

本文来源:flydean的博客

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

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
2年前
java中static关键字的使用
知识点:java中,static关键字修饰类的变量、方法、代码块、内部类场景:我们在创建类的方法和变量时,如果这个类在创建多个对象时,共用同一个属性或者方法,就可以使用static关键字修饰,因为static修饰的变量,在内存的静态域存在的值,被类的多个实例所共用,实际上我们在编写一个类时,就是在描述对象的属性和行为,并没有产生实质上的对
Wesley13 Wesley13
2年前
java基础常见面试题,这是一篇超长的随笔!!!
1\.Java基础部分.......................................................41、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?..42、Java有没有goto?.................................................4
Wesley13 Wesley13
2年前
Java进阶
到现在为止,我们都是在Java文件中直接定义类。这样的类出现在包(package)的级别上。Java允许类的嵌套定义。这里将讲解如何在一个类中嵌套定义另一个类。!(http://static.oschina.net/uploads/img/201601/21115000_D2R5.jpg)嵌套内部类Java允许我们在类的内部
Wesley13 Wesley13
2年前
Java锁机制浅析之 AQS
  一、内部原理  类继承结构  Lockpackage相关API继承结构,忽略掉了一些类,以便观察其特点:  ReentrantLock和ReentrantReadWriteLock都是借助内部类Sync来实现Lock接口。ReentrantReadWriteLock没有直接实现Lock接口而是内置了读锁ReadLock和写锁Write
Wesley13 Wesley13
2年前
Java 内部类理解
为什么使用内部类?答:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类有哪些?答:内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类这些内部类需要注意的点?成员内部类1)成员内部类中不能存在任何static的变量和方法2)成员内部类是依附
Wesley13 Wesley13
2年前
Java中匿名类的两种实现方式
使用匿名内部类课使代码更加简洁、紧凑,模块化程度更高。内部类能够访问外部内的一切成员变量和方法,包括私有的,而实现接口或继承类做不到。然而这个不是我说的重点,我说的很简单,就是匿名内部类的两种实现方式:第一种,继承一个类,重写其方法;第二种,实现一个接口(可以是多个),实现其方法。下面通过代码来说明:1.publicclass TestAnonymo
Wesley13 Wesley13
2年前
Java私有内部类实例化对象访问私有内部类中的方法
今天和小伙伴讨论私有类的对象创建问题,大家都知道外部类是不能设置为私有的,但是内部类可以设置为私有。问题是私有内部类是否可以实例化一个对象,并调用私有内部类中的方法和属性呢?答案是:Yes!Java语法规范既然允许创建私有的内部类,私有内部类中的方法肯定会被调用。要不然,私有内部类就失去了它的作用。于是小coder尝试写了如下代码。
Wesley13 Wesley13
2年前
Java oop第05章_多态、接口
一、为什么需要接口?  Java中当一个类继承父类时,最多也只能继承一个父类,扩展性会受到一定的限制,为了弥补这一缺陷,Java又提供了一种新的引用数据类型分类,叫接口。一个类只能继承一个父类,但可以实现多个接口。二、接口的定义和使用:  1.定义接口:使用interface关键
Wesley13 Wesley13
2年前
Java封装:访问控制
1、类的访问控制符有两种:public,default(默认的,什么都不用写)     default就是包内访问控制符。     当然对于内部类还可以有static修饰,而用static修饰的内部类叫作嵌套类。2、属性和方法的访问控制符有四种:private,default,protected,publi
小万哥 小万哥
1个月前
Java 抽象类与方法:实现安全性与代码重用
Java内部类简介在Java中,可以嵌套类(即类内部的类),称为内部类。嵌套类的目的是将属于一起的类分组,从而使您的代码更可读和可维护。访问内部类要访问内部类,请创建外部类的对象,然后创建内部类的对象:javaclassOuterClassintx10;c