1、接口是面向对象的关键特性:他们让你在不提供实现的情况下,指定应该做什么
近来,应为函数式编程非常适合并发和事件驱动编程,其重要性有所提升
接口的所有方法默认为公有方法,不用特意声明为public
实现类必须将接口方法声明为public,否则默认情况下,他们在包级别可访问。因为接口要求public级别访问,所以会报错
如果一个类只实现接口的某些方法,必须用abstract修饰
2、转换为接口类型
IntSequence digits = new DigitSequence();
这句话创建的对象是DigitSequence对象,内存中存储的是DigitSequence对象。但是对象的类型是IntSequence ,可以调用digits的IntSequence中的方法,如果子类重写了父类的方法则调用此方法时返回子类中此方法的结果。
对冉声明接口类型的变量是可能的,但是永远不会存在类型为接口的对象。所有的对象都是类的实例。
3、cast和instanceof
只能将一个对象强制转换为他的实际类或者他的父类之一。为了避免异常可以使用instanceof操作符先测试对象是否满足期望
if(sequence instanceof DigitSequence){ DigitSequence digits = (DigitSequence) sequence; }
4、常量
定义在接口中的任何变量自动为public static final
在接口中,无法拥有实例变量。接口指定行为,而不是状态。
5、静态方法和默认方法
静态方法:
早起Java中,所有方法必须是抽象的,现在可以添加两种有具体实现的方法:静态方法和抽象方法
之前,接口不能有静态方法,因为静态方法不符合接口作为抽象规范的定义。静态方法一般放在伴随类中
现在,特别是工厂方法在接口中非常有意义。
IntSequence digits = IntSequence.digitsOf(17); public interface IntSequence{ public static IntSequence digitsOf(int n){ return new DigitSequence(n); }
默认方法:
可以给接口的任意方法提供默认实现。
public interface IntSequence{ default boolean hasNext(){return true;} int next(); }
实现该接口的类可以选择重写覆盖hasNext方法或者选择继承默认的实现。
默认方法结束了,一个接口和实现该接口大多数或全部方法的伴随类,现在,你应该只在接口中实现方法。
默认方法的重要用途是:接口演化
1 public class Bag implements Collection
Java8在Collection中添加一个stream方法。如果stream方法不是默认方法,那么Collection原来的实现类因为没有实现新方法,将无法编译通过。
假设没有重新编译Bag,程序依然可以构造Bag实例(因为给接口添加方法是二进制兼容的http://blog.csdn.net/cool_way/article/details/8992874),但是Bag实例调用stream方法会抛出AbstractMethodError
/** * Returns a possibly parallel {@code Stream} with this collection as its * source. It is allowable for this method to return a sequential stream. * * <p>This method should be overridden when the {@link #spliterator()} * method cannot return a spliterator that is {@code IMMUTABLE}, * {@code CONCURRENT}, or <em>late-binding</em>. (See {@link #spliterator()} * for details.) * * @implSpec * The default implementation creates a parallel {@code Stream} from the * collection's {@code Spliterator}. * * @return a possibly parallel {@code Stream} over the elements in this * collection * @since 1.8 */ default Stream<E> parallelStream() { return StreamSupport.stream(spliterator(), true); }
解决默认方法冲突
如果一个一个接口既有实现类又有默认方法,此时必须解决冲突。
1 public class Employee implements Person,Indentified{ 2 public int getId(){return Indentified.super.getId();} 3 }
※如果一个类继承一个父类,又实现了一个接口,从父类和接口这两者继承了同样的方法。这样,只关心父类的方法,直接忽视来自接口的默认方法。
6、Comparable接口
1 public interface Comparable<T>{ 2 int compareTo(T other); 3 }
重写public T compareTo(T other)返回比较两者的差值,如果比较的对象是一个大负数,计算整数之差会产生一个大的正操作数,产生问题。可以使用Integer.compare。在计算浮点数,使用Double.compare来返回正确的浮点数,包括正负无穷。
可以使用Array.sort对任何Comparable对象的数组进行排序。
7、Comparator接口
这个更灵活一点。
1 public interface Comparator<T>{ 2 int compare(T first, T second); 3 }
8、UI回调
Java GUI 使用接口来回调,指定事件的操作。
1 public interface EventHandler<T>{ 2 void handle(T event); 3 } 4 5 class CancelAction implements EventHandler<ActionEvent>{ 6 public void handle(ActionEvent event){ 7 System.out.println(); 8 } 9 }