开发声明、实现和/或继承接口的代码,并使用 @Override注解
接口
- 与类一样,接口具有public或default的可访问性
- 接口中声明的字段默认为 PUBLIC、 STATIC 和 FINAL。与方法一样,即使您没有指定它们,编译器也会这样对待它们。即默认字段都为静态常量
所以接口中的成员变量不能未private,且必须要初始化赋值 - 接口可以extends任意数量的接口
为什么接口可以多实现,类只能单继承
如果你可以从多个类继承,当方法签名相同时,无法选择具体是哪个父类的方法,但接口因为只是定义,实现类是要重写父类方法的,避免了该问题
- 方法只有返回类型不同时,由于返回类型在方法的签名中没有被考虑,Java 编译器会生成一个错误:
interface Truck {
void accelerate();
}
interface CompactCar {
int accelerate();
}
class Car implements Truck, CompactCar {
// Java will complain about duplicate methods
// and incompatible return types
public void accelerate() {
// implementation
}
public int accelerate() {
// implementation
}
}
顺带提一句重载是可以改变方法的返回类型的
@override注解
为什么要加这个注解,因为的方法没有正确重写或实现该方法,编译器将生成错误。这是这个注解的的唯一功能。这在一些情况下很有用,比如一个输入错误导致了一个不太明显的错误:
interface CompactCar {
int accelerate();
}
class Car implements CompactCar {
// Compiler will mark an error about method
// "acelerate" not overriding or implementing something
@Override
public int acelerate() {
// implementation
}
}
JDK8接口新功能
java8提供了默认的方法,我们不必为它们提供实现,因为它们是非抽象的方法。允许使用带有方法体的方法
- 原因
如果一个接口被数百个类实现,现在要修改该接口,增加一个方法
1.数百个实现类必须都要增加实现否则编译报错,量大
2.某些原因无法更新或访问实现类代码
3.在功能上新增加的方法对于某些实现类来说并不需要,即不需要手动重写
默认Default方法
将默认方法添加到接口的主要原因是为了支持接口演进,为接口添加新功能,同时确保与为旧版本编写的代码兼容。
- 与抽象类的区别
1.抽象类单继承,接口可多实现
2.抽象类有实例字段具有状态属性,接口不可以
定义默认方法
interface Processable {
void processInSequence();
default void processInParallel() {
/** Default implementation goes here */
}
}
- 默认方法是public的,就像接口的其他方法一样
- 默认方法不能是final的。接口中所有方法都不能为final
- 默认方法无法被synchronized加锁,应该在实现类中实现
- 不能为Object类方法提供默认方法
如果接口具有带有这些签名的方法,编译器将抛出错误。原因是这些方法都是关于对象的状态。因为接口没有状态,所以这些方法应该在实现类中
boolean equals(Object o)
int hashCode()
String toString()
重写默认default方法
方法定义使用上,类的优先级高于接口,如果一个类重写了default的方法,那么类方法就是使用的方法。就和其他只是定义了方法签名的没有方法体的方法一样
- 即使该类将默认方法重新定义为 abstract,这也是正确的
interface Processable {
void processInSequence();
default void processInParallel() {
System.out.println("Default parallel");
}
}
// Class Task has to be abstract
abstract class Task implements Processable {
@Override
public void processInSequence() {
System.out.println("Processing in sequence");
}
@Override
public abstract void processInParallel();
}
- 调用方法的默认实现,可以使用接口的名称,后面跟着关键字 super
public void processInParallel() {
Processable.super.processInParallel();
}
- 当一个类的继承实例方法覆盖了默认的接口方法,则使用的也是继承的实例类重写的方法
interface Processable {
default void processInParallel() {
System.out.println("Default parallel");
}
}
class Process {
public void processInParallel() {
System.out.println("Class parallel");
}
}
public class Task
extends Process implements Processable {
public static void main(String args[]) {
Task t = new Task();
t.processInParallel(); //Class parallel
}
}
具有默认deafult方法的多个接口继承
两个接口具有相同的默认方法被子类实现时,如果子类不覆盖该默认方法则会编译报错
编译器不知道选择哪个,所以它会生成一个错误。在这种情况下,Task 必须提供一个实现(遵循前面的规则,即更具体的接口(或类)总是会胜过不那么具体的接口)来覆盖接口缺省方法并解决问题:
interface Parallelizable1 {
default void processInParallel() {
System.out.println("Parallelizable parallel");
}
}
public class Task
implements Processable1, Parallelizable1 {
@Override
public void processInSequence() {
System.out.println("Processing in sequence");
}
public static void main(String args[]) {
Task t = new Task();
t.processInParallel();
}
}
报错,必须要重写该默认方法
接口的静态方法
1.默认为public
2.不能被继承,但是类的静态方法可以被继承
3.使用时必须在方法前面加上接口名,因为接口不能被实例化
Comments | 0 条评论