接口、lambda表达式与内部类
-
接口中的所有方法都自动是public。不过,在实现接口时,必须把方法声明为public;否则,编译器将认为这个方法的访问属性是包可见性。
-
与接口中的方法都自动被设置为public一样,接口中的字段总是public static final。
-
尽管每个类只能有一个超类,但却可以实现多个接口。如果希望自己设计的类拥有克隆和比较的的能力,只要实现这两个接口就可以了:
class Employee implements Cloneable, Comparable -
为什么要引入接口的概念,为什么不将Comparable直接设计成一个抽象类呐?
每个类只能扩展一个类(Java中不支持多重继承),假如Employee类已经扩展了另一个类,例如Person,它就不能再扩展第二个类了。 但每个类可以实现多个接口。
-
可以为接口方法提供一个默认实现。必须用default修饰符标记这样一个方法。
public interface Comparable<T>{ default int compareTo(T other) { return 0; } }Comparable的每一个具体实现都会覆盖这个方法。不过,有时候默认方法可能很有用,比如实现类可以不覆盖这个默认方法,接口中 有这个默认方法的实现逻辑,实现类可以不用操心实现这个方法了。
-
解决默认方法冲突:
-
超类优先。如果超类提供了一个具体方法,同名而且有相同参数类型的默认方法会被忽略。
-
接口冲突。如果一个接口提供了一个默认方法,另一个接口提供了一个同名而且参数类型(不论是否是默认参数)相同的方法,必须覆盖这个方法来解决冲突。
- 如果一个 lambda 表达式只在某些分支返回一个值,而另外一些分支不返回值,这是不合法的。例如:
(int x)-> {if(x>=0) return 1} 就不合法。
- 为什么要使用内部类?
- 内部类可以对同一个包中的其他类隐藏。
- 内部类方法可以访问定义这个类的作用域中的数据,包括原本私有的数据。
-
内部类原先对于简洁的实现回调非常重要,不过如今 lambda 表达式在这方面可以做的更好。
- 一个内部类方法可以访问自身的数据字段,也可以访问创建它的外围类对象的数据字段。
-
为此,内部类的对象总有一个隐式引用,指向创建它的外部类对象。
- 静态内部类: 有时候,使用内部类只是为了把一个类隐藏在另外一个类的内部,并不需要内部类有外围类对象的一个引用。为此,可以将内部类声明为 static,这样就不会生成那个引用。