一 定义

类或者接口里再定义一个类。在内部类的结构中,不仅内部类可以方便地访问外部类的私有成员,外部类也同样可以访问内部类的私有成员。

二 种类

方法内部类、成员内部类、静态内部类、匿名内部类

1)方法内部类

首先我们看一个方法内部类的例子

class outer1 {
    //属性
    int i = 1;
    static int j = 2;
    //方法
    public void m() {
    	//隐式常量---在代码底层自动添加final---jdk1.8开始的
        int x = 1;
        //方法内部类可以继承父类也可以实现接口
        final class inner1 extends Object implements Cloneable{
            static final int k = 1;
            int z;
            public void n() {
            	 //访问外部类私有属性
                System.out.println(i);
                System.out.println(j);
                System.out.println(k);
                System.out.println(x);
            }
        }
        //创建内部类对象
        inner1 in1 = new inner1();
        int w = inner1.k;
    }
}

重上述的一段代码中我们可以总结内部类的特点。
1.可以在一个类的方法中定义
2.可以定义非静态属性、方法已经静态常量
3.方法内部类可以被final关键字修饰
4.可以拿到外部类的所有信息
5.可以拿到本方法中的常量

2)成员内部类

上代码

class outer2 {
    int i = 1;
    static int j = 2;
    //成员内部类可以继承父类也可以实现接口
    abstract class inner2 extends Object implements Cloneable{
        static final int k = 1;
        public void m() {
            System.out.println(i);
            System.out.println(j);
            System.out.println(k);
            outer2 ou2=new outer2();
            ou2.m();
        }
    }
    public void m(){
    }
}

创建成员内部类的对象

public class Demo {
    public static void main(String[] args) {
        outer2.inner2 inner2 = new outer2().new inner2(); 
    }
}

总结成员内部类特点:
1.在方法外类内定义一个类
2.可以定义非静态属性和方法以及静态常量
3.可以继承和实现
4.可以被访问权限修饰符以及final、abstract修饰
5.可以拿到外部类的所有信息

3)静态内部类

上代码

class outer3 {
    int i=1;
    static int j=2;
    static final class inner3 extends Object implements Cloneable{
        static  final int k=1;
        public void m(){
            System.out.println(k);
            System.out.println(j);
            System.out.println();//无法调用i
        }
    }
}

创建静态内部类对象

public class Demo {
    public static void main(String[] args) { 
        outer3.inner3 inner3 = new outer3.inner3();//外部类点出内部类对象
       }
}

总结:
1.在方法外类内定义一个static修饰的类
2.可以定义所有属性和方法以及静态常量
3.可以继承和实现
4.可以被访问权限修饰符以及final、abstract修饰
5.可以拿到外部类的所有的静态信息

4)匿名内部类

首先我们先建立一个抽象类

abstract class outer4{
    int i=1;
    static int j=2;
    abstract public void m();
}

创建匿名内部类

public class Demo {
    //匿名内部类作成员内部类
    outer4 inner44=new outer4() {
         @Override
         public void m() {
         //重写内容
         }
    };
    public static void main(String[] args) {  
    	//创建匿名内部类必须重写抽象方法,且匿名内部类只能创建一次!
    	//匿名内部类作方法内部类
        outer4 inner4 =new outer4() {
            @Override
            public void m() {
                System.out.println(i);
            }
        };
    }
}

总结:
1.匿名内部类主要的功能就是用于继承类或者实现接口,再进行重写
2.如果类/接口能被继承/实现就能具有匿名内部类的形式只能使用一次
3.如果匿名内部类定义在方法内就按方法内部类来使用,如果定义成员位置就按成员内部类使用

5)特殊情况

接下来我们来聊一聊在接口里创建类与接口的情况

public class InnerDemo5{
     //默认被static修饰
     interface IDemo2{}
     interface IDemo2{}
     public static void main(String[] args){
          System.out.println(ODemo.IDemo1.j);
    }
} 
  
interface ODemo{
     //接口内部定义一个类
     //默认被static修饰
     class IDemo{
     static int i=1; }
     //内部接口
     //默认被static修饰
     interface IDemo1{
         static int j=2;
     }
}