Java8新特性(二) 接口中的默认方法和静态方法(面试题:抽象类和接口的区别)
程序员文章站
2022-06-13 20:39:47
...
1. 为什么要有这个特性?
抽象类和接口设计目的
- 接口的设计目的,是对类的行为进行约束(更准确的说是一种 “有” 约束,因为接口不能规定类不可以有什么行为),也就是提供一种机制,可以强制要求不同的类具有相同的行为。它只约束了行为的有无,但不对如何实现行为进行限制。对 “接口为何是约束” 的理解,我觉得配合泛型食用效果更佳。
- 而抽象类的设计目的,是代码复用。当不同的类具有某些相同的行为 (记为行为集合 A),且其中一部分行为的实现方式一致时(A 的非真子集,记为 B),可以让这些类都派生于一个抽象类。在这个抽象类中实现了 B,避免让所有的子类来实现 B,这就达到了代码复用的目的。而 A 减 B 的部分,留给各个子类自己实现。正是因为 A-B 在这里没有实现,所以抽象类不允许实例化出来(否则当调用到 A-B 时,无法执行)。
首先,之前的接口是个双刃剑,好处是面向抽象而不是面向具体编程,缺陷是,当需要修改接口时候,需要修改全部实现该接口的类,目前的 java 8 之前的集合框架没有 foreach 方法,通常能想到的解决办法是在 JDK 里给相关的接口添加新的方法及实现。然而,对于已经发布的版本,是没法在给接口添加新方法的同时不影响已有的实现。所以引进的默认方法。他们的目的是为了解决接口的修改与现有的实现不兼容的问题。-- 菜鸟教程
2. 接口的默认方法和静态方法
默认方法:Java8 允许在接口中增加默认方法,默认方法在实现类中可以不去实现它,但是如果接口中有默认方法,实现类将默认继承这个默认方法,当然如果有需要的话可以在实现类中覆盖抽象方法,所以很容易得出默认方法的使用方式:用实现类的实例来直接点出这个默认方法。而当被覆盖后,接口中的默认方法调用为:接口名.super.默认方法。
静态方法:允许在已有的接口中增加静态方法,需要提供方法的实现。静态方法属于接口本身,不被实现类所继承。所以说静态方法和普通的静态方法使用方式相同,直接使用接口的类名点方法名。
interface Animal{
void eat();
//静态方法
static void fly(){
System.out.println("飞");
}
//默认方法
default void run(){
System.out.println("跑");
}
}
public class Bird implements Animal{
@Override
public void eat() {
System.out.println("我喜欢吃虫子");
}
public void run(){
Animal.super.run();//调用接口的默认方法
System.out.print("我喜欢");
Animal.fly();//调用接口的静态方法
}
public static void main(String[] args) {
Bird bird = new Bird();
bird.eat();
bird.run();//调用覆盖后的方法
}
}
结果:
我喜欢吃虫子
跑
我喜欢飞
3. 抽象类和接口语法和使用上区别(面试题)
- 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 pubic static final 类型的
- 一个类可以实现多个接口但是只能继承一个抽象类
- 抽象类和抽象类中的抽象方法都需要有关键字是abstract ,接口类的关键字是interface
- 抽象类中可以有静态代码块,而接口中不能有静态代码块
java8以后过时的说法
-
抽象类中可以有普通方法也可以有抽象方法而接口中方法只能是抽象的
-
抽象类中可以有静态方法,而接口中不能有静态方法
-
一个类实现接口的话就必须实现接口中所有的方法而继承抽象类的话不一定要全部实现