内部类
    在一个类的内部 定义另一个类 成员内部类
    在成员方法内 定义一个类 局部内部类
    特点:简化代码结构 使类和类的从属关系更加明确
    缺点:外部不方便去调用内部类 导致内部类的重用受到限制

    1. Class Classes{
    2. public String cName;
    3. public Class Students{
    4. public String name;
    5. syso(Classes.this.cName+""+this.name);
    6. }
    7. public void showStudent(){
    8. Students stu = new Students();
    9. stu.内部类变量 方法
    10. }
    11. public void showTeacher(){
    12. int num=5;//如果这个局部变量被局部内部类访问 则这个变量默认是常量
    13. String name = "";//如果局部内部类变量与局部变量重名 则访问的是局部内部类的变量
    14. class Teacher{
    15. public String name;
    16. public void show(){
    17. syso(name+num);
    18. }
    19. }
    20. //局部内部类的调用需要在方法中创建类的对象
    21. Teacher teacher = new Teacher();
    22. teacher.show();
    23. }
    24. }
    25. 测试类
    26. new Classes().new Students().内部类变量 方法
    27. new Classes().showTeacher();//测试类中通过外部类对象调用包含局部内部类的方法而调用局部内部类的执行
    28. 内部类作用:
    29. 1.可以不通过创建接口的实现类 就实现接口
    30. 2.对于特定的接口 使用内部类的方案 可以通过lambda表达式进行再优化

    1.可以不通过创建接口的实现类 就实现接口
    当一个类只负责实现接口而没有其他的任何内容时 可以省略编写这个实现类 而通过内部类的形式对接口进行实现 在真正准备调用接口方法时才去实现抽象方法
    public interface Lesson{
    public void showLesson();
    }

    Lesson lesson = new Lesson(){
        @Override
        public void showLesson() {
            // TODO Auto-generated method stub
            System.out.println("好好学习");
        }
    };
    可以使用 lesson.showLesson();
    就省略了当前接口实现类的编写过程
    
    接口作为方法的参数---》要在调用方法前 准备实参时实现接口的方法
    接口作为方法的返回值---》要在返回return关键字前 准备实现了方法的接口
    

    抽象方法带参数、带返回值的接口

    &&在方法中去调用接口
        public void show(){
            Usb usb = new Usb() {
                @Override
                public String show(int i) {
                    // TODO Auto-generated method stub
                    if(i==1) {
                        return "U盘数据传输中";
                    }else if(i==2) {
                        return "风扇转起来";
                    }else {
                        return "鼠标跑了";
                    }
                }
            };
            //实现后在调用方法时给参数 处理方法的返回结果
            System.out.println(usb.show(2));
        }
    &&这个接口作为一个方法的参数的时候
        保证在调用执行这个方法时 接口已经被实现 传入这个接口的实现类对象(内部类)
        要注意接口中抽象方法的参数来源 在最终调用这个抽象方法前准备好 给实参
        Utils类中的一个方法
        public void showUsb(Usb u,int i) {
            //调用接口中抽象方法前准备好所需的参数
            System.out.println(u.show(i));
        }
        测试类中
        //传入一个接口的实现类对象作为实参  这个接口必须已经实现了
        u.showUsb(new Usb() {
            @Override
            public String show(int i) {
                // TODO Auto-generated method stub
                if(i==1) {
                    return "U盘数据传输中";
                }else if(i==2) {
                    return "风扇转起来";
                }else {
                    return "鼠标跑了";
                }
            }
        }, i的真实值);
    
    
    &&这个接口作为方法的返回值
        保证在方法返回前 一定要对这个接口进行实现 返回接口的实现类对象(匿名内部类)
        此时都属于设计方法 不考虑参数真正的值
        调用方法就是调用返回值就是调用接口的实现类对象 使用这个对象调用抽象方法 给实参
        Utils类中的方法
        public Usb getUsb() {
            return new Usb() {
                @Override
                public String show(int i) {
                    // TODO Auto-generated method stub
                    if(i==1) {
                        return "U盘数据传输中";
                    }else if(i==2) {
                        return "风扇转起来";
                    }else {
                        return "鼠标跑了";
                    }
                }
            };
        }
        测试类中
        //在获得接口实现类对象后 调用实现的抽象方法 给实参
        System.out.println(u.getUsb().show(i的真实值));
    

    练习:
    定义一个做饭功能 DoCook 厨艺方法String cook(String)
    实现原则:
    1.”面” 返回 “可以泡碗方便面”
    2.”土豆” 返回”满汉全席”
    3.”泥巴” 返回”泥巴大餐”
    需求1.在main方法中选择传入食材 展示返回结果

    需求2.创建void showCook(DoCook) 参数为接口实现类对象 
            调用这个方法前 用户选择面 土豆 泥巴 获得对应的接口实现类传入并展示结果
    
    需求3.创建DoCook getCook(String) 参数为传入的食材
            调用这个方法前 用户选择面 土豆 泥巴 方法中对对应的食材进行实现并返回展示
    

    2.对于特定的接口 使用内部类的方案 可以通过lambda表达式进行再优化
    函数式接口:接口中只有一个抽象方法的接口 叫做函数式接口 才能使用lambda优化
    @FunctionalInterface 在接口类的类名上添加此注解 如果不是函数式接口 则报错

    如何使用:
        找到实现接口的代码块 将new 接口之后的实现过程替换为lambda表达式方案
    创建接口引用 = (抽象方法参数列表)->{【return】抽象方法方法体};
    接口的引用调用实现的方法
    
    @FunctionalInterface//函数式接口注解
    public interface Cook {
        public String show(int num , String n);
    }
    **lambda表达式直接在测试类main方法中
    Cook cook = (int num , String n)->{return "做"+num+"份"+n+"饭";};
    System.out.println(cook.show(5,"炸鸡"));
    
    **lambda表达式作为方法的参数
        要在传入实参的时候使用lambda表达式实现 再传参
        public void showU(Cook c,int num,String n) {
            System.out.println(c.show(num, n));
        }
        测试类中 调用同时准备实参
        Utils u = new Utils();
        u.showU((int num , String n)->{return "做"+num+"份"+n+"饭";}, 5, "炸鸡");
    
    **lambda表达式作为方法的返回值
        要在返回return的时候使用lambda表达式实现 再返回
        public Cook showU1() {
            return (int num,String n)->{return "做了"+num+"份"+n;};
        }
        测试类
        Utils u = new Utils();
        System.out.println(u.showU1().show(5, "炸鸡"));