aoi学院

Aisaka's Blog, School of Aoi, Aisaka University

Java-Java抽象类和接口的区别

语法层面上的区别

  • 抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract (隐式声明)方法;
  • 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final(隐式声明)类型的(必须在声明时赋值);
  • 接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
  • 一个类只能继承一个抽象类,而一个类却可以实现多个接口。

设计层面上的区别

  1. 抽象类是对一种事务的抽象,是对整个类进行抽象,包括属性,行为(方法)。接口是对行为(行为)的抽象。如果一个类继承或实现了某个抽象类,那么一定是抽象类的种类(拥有同一种属性或行为的类)。

  2. 设计层面不同,抽象类作为很多子类的父类,是一种模板设计,而接口是一种规范,它是一种辐射式设计,也就是说对于抽象类,如果需要添加新的方法,可以直接在抽象方法中添加实现,子类可以不用变更,而对于接口不行,如果接口进行了变更,那么实现它的类都需要做变更。


示例

  • java接口的修饰符:abstract(默认不写。interface本身就是抽象的,加不加abstract都一样)
  • 接口中字段的修饰符:public static final(默认不写)

解释如下:

  • public: 使接口的实现类可以使用该常量;
  • static:接口不涉及和任何具体实例相关的细节,因此接口没有构造方法,不能被实例化,没有实例变量,只有静态变量。(static修饰就表示它属于类的,随的类的加载而存在的,当JVM把字节码加载进JVM的时候,static修饰的成员已经在内存中存在了。如果是非static的话,就表示属于对象的,只有建立对象时才有它,而接口是不能建立对象的,所以接口的常量必须定义为static。)
  • final:接口中不可以定义变量,即定义的变量前都要加上final修饰,使之成为常量,且必须赋初始值!(final修饰就是保证接口定义的常量不能被实现类去修改,如果没有final的话,由子类随意去修改的话,接口建立这个常量就没有意义了。
  • 接口中方法的修饰符:public abstract(默认不写)

接口方法仅仅描述方法能做什么,但是不指定如何去做,所以接口中的方法都是抽象的(abstract方法)


注意

接口和抽象类分别在什么时候使用

  1. 如果拥有一些方法,并想让他们中的一些有默认的具体实现,请选择抽象类

  2. 如果想实现多重继承,那么请使用接口,由于java不支持多继承,子类不能继承多个类,但一个类可以实现多个接口,因此可以使用接口来解决。

  3. 如果基本功能在不断变化,那么就使用抽象类,如果使用接口,那么每次变更都需要相应的去改变实现该接口的所有类。

JDK8中接口的默认方法和静态方法

JDK8中,Oracle引入默认方法和静态方法,用来减少抽象类和接口的差异,可以在接口中提供默认的实现方法并实现该接口的类不用强制去实现这个方法。JDK8中接口的静态方法只能通过接口名直接去调用,接口中的默认方法因为不是abstract的,所以可重写,也可以不重写。

优先级问题

当一个类,既继承了一个父类,又实现多个接口,父类中的成员方法与接口中的默认方法重名,子类就近选择执行父类的成员方法

接口的继承

一个接口能继承另外一个或者多个接口,这和类之间的继承比较相似,接口的继承使用extends关键字,子接口继承父接口的方法.如果父接口中的默认方法有重名的,那么子接口需要重写一次

默认方法

使用default修饰,不可省略,供子类调用或者子类重写

可以继承,可以重写,二选一,但是只能通过实现类的对象来调用

接口中,有多个默认方法时,实现类都可继承使用,如果继承方法有重名的,必须重写一次

其他

  1. 接口中无法定义成员变量,但是可以定义常量,其值不可以改变,默认使用public static final修饰

  2. 接口中,没有构造方法,不能创建对象

  3. 接口中,没有静态代码块


参考资料

https://blog.csdn.net/weixin_66813230/article/details/123510909