读《Java核心技术 卷I》第六章 接口、lambda表达式与内部类
接口
接口中所有的方法都自动是public方法。因此,在接口中声明方法时,不必提供关键字public。
要讲类声明为实现某个接口,需要使用关键字implements。
接口不是类,不能使用new实例化一个接口,但是可以使用多态,声明接口变量。
接口中不能包含实例字段,但是可以包含常量。与接口中的方法都自动被设置为public一样,接口中的字段总是public static final。
Java语言规范建议不要提供多余的关键字。
每一个类只能有一个超类,但是可以实现多个接口。
抽象类与接口
抽象类表示通用属性存在一个严重的问题。每个类只能扩张一个类,但是接口可以实现多个接口。
实际上,接口可以提供多重继承的大多数好处,同时还能避免多重继承的复杂性和低效率性。
可以为接口提供一个默认实现。必须用default修饰符标记这样一个方法。
如果先在一个接口中讲一个方法定义为默认方法,然后又在超类或另一个接口中定义同样的方法,规则如下:
-
超类优先。如果超类提供了一个具体方法,同名而且有相同参数类型的默认方法会被忽略。
-
接口冲突。如果一个接口提供一个默认方法,另一个接口提供了一个同名而且参数类型(不论是否是默认参数)相同的方法,必须覆盖这个方法来解决冲突。
另一种情况,一个类扩展了一个超类,同时实现了一个接口,并从超类和接口继承了相同的方法。这种情况下,只会考虑超类方法,接口的所有默认方法都会被忽略。这正是“类优先”原则。
lambda表达式
lambda表达式是一个可传递的代码块,可以在以后执行一次或多次。
对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式。这种接口称为函数式接口。
lambda表达式有3部分:1.一个代码块;2.参数;3.自由变量,这是指非参数而且不在代码中定义的变量。
注:在lambda表达式中,只能应用值不会改变的变量。
如果在lambda表达式中更改变量,并发执行多个动作是就会不安全。
使用lambda表达式的重点是 延迟执行 。
原因:
-
在一个单独的线程中运行代码;
-
多次运行代码;
-
在算法的适当位置运行代码(例如,排序中的比较操作)
-
发生某种情况时执行(如,点击了一个按钮,数据到达,等等);
-
只在必要时才运行代码。
内部类
内部类时定义在另一个类中的类。
-
内部类可以对同一个包中的其他类隐藏
-
内部类方法可以访问定义这个类的作用域中的数据,包括原本私有的数据。
局部内部类
声明局部内部类时不能有访问说明符(即public或private)。局部类的作用域被限定在声明这个局部类的快中。
局部类有一个很大的优势,即对外部世界完全隐藏。
相对于其他内部类,局部类还有一个优点,它不仅能够访问外部类的字段,还可以访问局部变量!
不过,局部变量必须是事实最终变量。
例:在一个方法中声明局部内部类
public void start(){
class Inner {
public void method(){ }
}
var inner=new Inner();
inner.method;
}
匿名内部类
假如只想创建这个类的一个对象,甚至不需要为这个类指定名字。
它的含义:创建一个类的新对象,这个类实现了接口。
一般语法:
new SuperType(construction parameters){
inner class methods and data
}
注:如果构造参数列表的结束小括号后面跟一个开始大括号,就是在定义匿名内部类。
尽管匿名内部类不能有构造器,但可以提供一个对象初始化块。
例:var count=new Person("jack"){
{ initialization }
}
静态内部类
可以将内部类声明为static,这样就不会生成那个引用。
常规内部类
常规内部类没有用static修饰且定义在在外部类类体中。
常规内部类中的方法可以直接使用外部类的实例变量和实例方法。在常规内部类中可以直接用内部类创建对象。

浙公网安备 33010602011771号