接口、lambda表达式与内部类
- 接口:用来描述类应该做社么,而不指定它们具体应该如何做
- lambda表达式:一种很简洁的方法,用来创建可以在将来某个时间点执行的代码块
- 内部类:定义在另外一个类的内部,它们的方法可以访问包含它们的外部类的字段。内部类技术在设计具有相互协作关系的类集合时很有用。
- 代理:实现任意接口的对象
接口
接口的概念
接口不是类,而是对希望符合这个接口的类的一组需求(定义规范)
- 接口中的所有方法都自动时public方法,在接口中声明方法时,不需要提供关键字public。
- 接口中的字段总是 public static final
- 提供实例字段和方法实现的任务应该由实现接口的那个类来完成。
- 在实现接口时,必须把方法声明为public。
- Comparable接口的文档建议CompareTo方法应当与equals方法兼容。
接口的属性
- 接口不是类,不能new运算符实例化接口,即不能构造接口对象
x=new Comparable(...);//ERROR,不能构造接口对象
- 可以声明接口变量
Comparable x;//可以声明接口变量
- 接口变量必须引用实现了这个接口的类对象
Comparable x;//可以声明接口变量
x= new 实现了Comparable接口的类(...)//实现Comparable接口类的构造器
- 可以使用、将想要实现的各个接口分隔开。
接口与abstract类
- 使用abstract类标识通用属性存在一个严重的问题,每个类只能扩展一个类。
java不支持多重继承,主要原因为多重继承让语言变得非常复杂(如同C++的虚基类,控制规则和横向指针类型转换),或效率会降低(如同Eiffel) - 接口可以提供多重继承的大多数好处,同时还能避免多重继承的复杂性和低效性。
静态和私有方法
- jdk 8中允许在接口中增加静态方法。
默认(default)方法
- 可以为接口方法提供一个默认实现,必须用default修饰符标记该方法。
解决默认方法冲突
- 千万不要让一个人default方法重新定义Object类中的某个方法。由于“类优先”规则,这样的方法绝对无法超越Object中的方法。
接口与回调
- 回调:是一种常见的设计模式。在这种模式中,可以指定某个特定事件发生时应该采取的动作。
lambda表达式
为什么引用lambda表达式
- lambda表达式是一个可传递的代码块,可以在以后执行一次或多次。
- 在java中传递一个代码段并不容易,不能直接传递代码块。java是一种面向对象的语言,所以必须构造一个对象,这个对象的类需要有一个方法包含所需的方法。
lambda表达式的语法
(String first,String second)
-> first.length() - second.length()
lambda表达式就是一个代码块,以及必须传入代码的变量规范。
- 如果可以推导出lambda表达式的参数类型,可以忽略其类型。
- 如果方法只有一个参数,而且这个参数的类型可以推导得出,那么甚至可以忽略小括号。
函数式接口
- 只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式。这种接口称为函数式接口
方法引用
lambda表达式涉及一个方法。
var timer = new Timer(1000, event -> System.out.println(event));
//表达式System.out::println是一个方法引用,表示编译器生成一个函数式接口的实例,覆盖这个接口的抽象方法来调用给定的方法。
var timer = new Timer(1000, System.out::println);
- object::instanceMethod
- Class::instanceMethod
- Class::staticMethod
构造器引用
- 构造器引用与构造方法类似只不过方法名为new。例如Person::new是Person构造器的一个引用。
Person[] people=stream.toArray(Person[]::new);
变量作用域
- 在lambda表达式中,只能引用值不值不会改变的变量。
- 在lambda表达式中引用一个变量,而这个变量可能在外部改变是不合法的。
- lambda表达式中捕获的变量必须实际上是事实最终变量(这个变量初始化后就不会再为它赋新值)。
处理lambda表达式
使用lambda表达式的重点是延迟执行,如果想要立即执行代码,完全可以直接执行,而无须把它包装在一个lambda表达式中。
延迟执行的原因:
- 在一个单独的线程中运行代码
- 多次运行代码
- 在算法的适当位置运行代码(排序中的比较操作)
- 在发生某种情况时执行代码(点击了一个按钮,数据到达等)
- 只在必要时才运行代码
内部类
内部类是定义在另一个类中的类。
使用内部类的原因:
- 内部类可以对同一个包中的其他类隐藏
- 内部类方法可以访问定义这个类的作用域中的数据,包括原本私有的数据
//TODO
代理
//TODO
Comments | 0 条评论