## 接口 > 关键字: `interface`修饰 > > 只负责声明函数 ,不负责具体实现 > 接口中的所有定义其实都是抽象的,隐藏了`public abstract` > > 通过`Idea`编写,可以看出`public abstract`是灰色的,可以默认不写 ~~~  public interface UserService {            // public abstract可以不写      public abstract void add(String username);  } ~~~ > 接口都需要一个实现类 : `Impl`结尾进行命名 > > 关键字:`implements` > > 实现了接口中的类,就需要重写接口中的方法 > > 可以实现伪多继承 > 接口中定义常量 ~~~  // public static final可以隐藏  public static final int AGE = 99; ~~~ **作用** 1. 约束 2. 定义一些方法,让不同的人实现 3. `public abstract`修饰方法可以隐藏 4. `public static final`修饰常量可以隐藏 5. 接口不能被实例化,接口中没有构造方法 6. `implements`可以实现多个接口 7. 必须要重写接口中的方法! ## 内部类(奇葩。。。) ~~~  public class Outer {  ​      private int id;  ​      public void out() {          System.out.println("这是外部类的方法");     }  ​      public class Innner {          public void in() {              System.out.println("这是内部类的方法");         }     }  }  ​ ~~~ ~~~  // 实例化内部类的操作  public static void main(String[] args) {      // 外部类      Outer outer = new Outer();            // 内部类      Outer.Inner inner = new outer.new Inner();  } ~~~ > 匿名内部类 > > 没有名字初始化类,不用将实例保存到变量中 ~~~  public class Test {      public static void main(String[] args) {          new Apple().eat();                    UserService userService = new UserService() {              @Override              public void hello() {                               }         }     }  }  ​  class Apple {      public void eat() {          System.out.println("1");     }  }  ​  interface UserService {      void hello();  } ~~~ ## 给憨憨写的阶乘的实现原理 > 一个数的阶乘 > > 当这个`数 = 1`的时候,算式为:`1 * (1 - 0) = 1`,所以1的阶乘就是1 > > 当这个`数 = 2`的时候,算式为:`2! = 2 * 1 = 2 * (2 - 1) = 2`,所以2的阶乘就是 > > 前2个数为特殊情况 > > 假设这个数为`n` > > `n = 1` , `n! = 1 * (1 - 0)` > > `n = 2`,`n! = 2 * (2 - 1)` > > `n = 3`,`n! = 3 * (3 - 1) * (3 - 2)` > > `....等等等....` > > 由此引发出递归的思想 ~~~  public class Test {      pulic static void main(String[] args) {          System.out.println(5); // 120     }            public static int F(int n) {     // 首先来处理2个特殊情况          if (n == 1) {              // 如果 n 和 1 相等,直接返回结果为1              return 1;         }          if (n == 2) {              // 如果n 和 2 相等,直接返回结果为2              return 2;         }                    if (n > 2) {              return n * F(n - 1);         }     }  } ~~~ > 上述还可以简化为 ~~~  public class Test {      pulic static void main(String[] args) {          System.out.println(5); // 120     }            // 因为这是在java语言中,需要返回值,所以更改之后写成这样      public static int f(int n) {          if (n == 1) {              return 1;         } else if (n == 0) {              return 1;         } else {              return n * f(n - 1);         }     }  } ~~~ > 5代入的执行流程 > > `n = 5`,第一个判断不执行,`n`现在是`>=`2的,就执行`return n * F(n - 1);`,这就相当于小时候的数学的方程式代入感一样,5代入,`5 * F(4)` , 这里的`F(4)`又是调用了一遍这个函数,`F(4) = 4 * F(3)`,依次下去,就会最终变成`5 * 4 * 3 * 2 * 1`;