详解内部类和内部接口 - 极悦
首页 课程 师资 教程 报名

详解内部类和内部接口

  • 2020-10-20 17:57:39
  • 977次 极悦

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


一、内部类

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


1.静态内部类

我们在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()来实例化内部类。


2.非静态内部类

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。


3.静态方法内部类

我们可以在静态方法中定义一个类,这个类其实就相当于方法中的变量,这个变量当然不能是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();

}

}

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


4.非静态方法的内部类

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

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

}

}


5.匿名类

最后一个,匿名类,直接在需要的时候实例化的类。匿名类我们遇到了很多次了,比如在构建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;

}

}


总的来说,内部类和内部接口其实可以看成一个变量,这样代入进去方便我们理解。对于内部类和内部接口,在本站的Java基础教程中有更加详细的讲解,欢迎小伙伴们前来观看学习。


选你想看

你适合学Java吗?4大专业测评方法

代码逻辑 吸收能力 技术学习能力 综合素质

先测评确定适合在学习

在线申请免费测试名额
价值1998元实验班免费学
姓名
手机
提交