我们来聊聊抽象类和接口吧,复习和总结一下。
抽象类
类是具有相同功能和属性的对象的集合,而抽象类是对类的高度抽象,在类层次中处于上层,位于上层的类更具有通用性。
抽象类用abstract关键字修饰。通俗得讲,含有抽象方法的类就是抽象类。但是,一个类即使没有抽象方法也是可以声明为抽象类的,如果你不想让这个类创建实例的话。
抽象类的一些特性:
- 抽象类有构造方法,但不可以被实例化。构造方法是子类用来初始化父类数据的
- 含有抽象方法的类一定是抽象类
- 抽象类中可以有抽象方法也可以有普通方法
- 抽象类的子类如果不能定义全部抽象方法则这个类也必须是抽象类。
- abstract关键字和final,private冲突
- 抽象类体现的is a的关系
接口
接口是比抽象类更抽象的概念,官方定义是这个样子的:
接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)
接口用interface关键字来声明,接口的一些特性如下
- 接口没有构造函数,也不可以被实例化
- 接口中的方法默认是public abstract的,变量默认是public static final的
- 接口可以被扩展,一个接口可以继承多个接口
- 接口体现的是 like a 的关系
java1.8以后接口增加了新的特性
1、可以有静态方法
public interface Path {
public static Path get(String first,String... more){
return FileSystem.getDeafult().getPath(first,more);
}
}
以方静态方法都是在工具类中和接口同步出现的,如Collection/Collections;加入自己实现一个接口的时候,就不需要创建一个额外的工具类了。
2、可以默认方法
interface demo{
default int d(){
return 0;
}
}
1、作为伴随类的新实现方式,就是缺省适配器。
2、接口不断演化下,添加了新的方法,而默认方法的存在可以让代码向前兼容。
为什么有了抽象类还要接口
看起来抽象类除了多继承以外,完全可以完成接口所作的事情,为什么还需要定义接口呢?
1、避免java单继承的局限
2、避免多继承带来的复杂性和低效性
3、面向接口编程带来的优势。降低程序间的耦合,易扩展,易维护
那么什么是面向接口编程
就是说在系统的分析和架构中,分清层次和依赖关系,每个层次不是直接向上层提供服务(对象实例化在上层中)。而是定义一组接口,仅向上层暴露其接口,上层对于下层仅仅是接口依赖而不是具体类。
这么做的一个好处就是系统的灵活性大大提高,当下层需要改变时,只要接口不变那么上层不需要做任何改变。比如说你的鼠标坏了,你需要换一个鼠标,那么电脑其他的东西都不用改变,你只要换一个符合接口的新鼠标就好了。
另一个好处就是不同层次的开发可以并行,只要符合接口的规范即可,很大的提升了效率。
解决默认方法冲突
如果在一个接口中将一个方法定义为默认的方法,然后又在超类或另一个接口中定义了同样的方法,那么会发生什么情况?
- 超类优先。如果超类提供了一个具体方法,同名且有相同参数类型的默认方法会被忽略。
abstract class Person {
public abstract String getName();
}
interface Name {
default String getName() {
return "name";
}
}
class Teacher extends Person implements Name {
@Override
public String getName() {
return "lisi";
}
}
public class Something2 {
public static void main(String[] args) {
System.out.println(new Teacher().getName());
}
}
//输出的结果是lisi
- 接口冲突。如果一个超接口提供了一个默认方法,另一个接口提供了一个同名且参数相同的方法,则必须覆盖这个方法来解决冲突。
interface Person {
default String getName() {
return "hanmeimei";
}
}
interface Name {
default String getName() {
return "name";
}
}
class Teacher implements Person,Name {
@Override
public String getName() {//只要提供同名方法就可以解决冲突
return Person.super.getName();
}
}
总结
- 抽象类和子类的关系是is a,接口和子类的关系是like a的
- 抽象类更多是基于代码复用,而接口则偏向实现多态性
抽象类和接口的区别图:
有关于接口方法在前面已经提到了,java1.8后有较大改动。
参考文章:
多态抽象类和接口
接口和抽象类存在的意义和适用场景以及为什么要使用接口
Java接口和抽象类用法总结,使用场景
(推荐)