抽象类和接口有什么区别

145 阅读5分钟

摘要:

抽象类和接口,都是用来抽象具体的,但是在层级维度上表示又是不同的,抽象类是用来抽象类别的,而接口是用来抽象具体功能的。在语法定义和使用上有相同点,但也存在一些差异。

抽象类和接口介绍

抽象类介绍

1、抽象类不能被实例化,只能被子类继承,抽象类的声明使用 abstract 关键字;abstract 作用在类上,表示该类是一个抽象类;在抽象类中,abstract 作用在方法上,表示该方法是一个抽象方法。

2、抽象类中可以有抽象方法(也可以不定义抽象方法),也可以有普通方法;有抽象方法的类一定是抽象类,而抽象类不一定要有抽象方法。

3、抽象类中的抽象方法,访问修饰符只能是 protected、public ,默认是 public ;抽象方法不能是 private 修饰,否则会报 Illegal combination of modifiers: 'abstract' and 'private' 。

4、一个子类继承一个抽象类,需要子类必须实现父类的所有抽象方法,否则子类也需要定义为抽象类;并且,类的继承是单继承,接口的继承是多继承;类的继承使用 extends 关键字 。

5、抽象类中,可以包含属性、方法、构造方法;但是,构造方法是不能被子类继承的,只能被子类调用,并且构造方法的调用通过 super 关键字。

6、抽象类定义如下

public abstract class BaseConfig{


     // 常规变量
     protected Object v1;
     
     // 静态变量
     public static Object V2;
     
     // 常量
     public static final Object V3;
     

     // 普通方法
     public void cfg1(){
     }
     
     // public 修饰
     public abstract void cfg2();
     
     // protected 修饰
     protected abstract void cfg3();
     
     // 抽象方法不能被 private 修饰,Illegal combination of modifiers: 'abstract' and 'private'
     //private abstract void cfg4();
     
     
}

接口介绍

1、java 中接口的声明使用 interface 关键字。 类的声明使用 class 关键字。

2、接口中能定义变量、方法;其中,接口中定义的变量是被隐式的 public static final 修饰的,接口中定义的方法是被 public abstract 修饰的(java8 之前);java8 开始,接口中可以定义 default 方法。

3、接口是支持多继承的,interface A extends B ,C , D {};间接上解决了 Java 的单继承问题。

4、一个类可以实现多个接口,class A implements B,C,D{}。

5、java8 对接口增加的新特性

(1)、 default method 默认方法 ,java8 允许在接口中定义非抽象方法;

接口中的非抽象方法,需要使用 default 关键字修饰;

其中,接口中的 default 方法,可以不被实现类所实现,实现类只能调用接口中的 default 方法,或者重写;

如果子类实现类实现了多个接口,并且这些接口中包含多个一样的 default 方法,则子类必须重写重名的 default 方法。

(2)、 static method 静态方法,java8 允许使用 static 关键字修饰一个方法,并提供实现,该方式叫接口静态方法;

静态方法只能通过接口调用,如 接口名.静态方法名 。

6、接口的定义示例如下:

public interface H5OpenApi extends OpenApi, BaseApi{

     // 接口中只能定义常量
     
     Object V;

     void func1();
     
     void func2();
     
     default void func3(){
     
     }
}

抽象类和接口区别

相同点

1、抽象类和接口都不能被实例化。

2、接口的实现类以及抽象类的子类,只有实现了它们的抽象方法后才能被实例化。

不同点

1、接口中只有方法的定义,不能有实现,java8允许定义 default 方法;而抽象类中,可以定义抽象方法,也可以定义普通方法,但不能定义 default 方法。

2、接口实现的关键字是 implements ,继承抽象类(或者其非 final 修饰的类)使用 extends 关键字;其中,接口的继承也是使用 extends 关键字;

3、在侧重点上,接口是注重功能的定义,而抽象类则是注重所属关系的定义。

5、接口中成员变量默认是被 public static final 修饰,必须赋初始值,且不能更改;

接口中所有成员方法都是 public abstract 修饰的(java8 的 default 方法除外);

抽象类的成员变量默认是 default 修饰的,并且在子类中可以重新定义,也可以被重新赋值;

接口和抽象类中的抽象方法都是被 abstract 修饰的,不能被 private 、static 、synchronized 和 native 等关键字修饰,只有有方法声明,不能有方法体 。

实际项目使用技巧

1、抽象类和接口都是用来抽象具体对象的,但是在层级上,接口的抽象级别更高

2、抽象类是用来抽象类别的,而接口是用来抽象功能的。

3、提供核心能力一般是采用接口的方式,比如Dubbo方式暴露服务

4、泛化关系,指的是类或者接口(子类、子接口)继承另外类(父类、父接口)的功能, 并可以添加自己的新功能。继承是类与类、接口与接口的的常见关系,java 是使用 extends 表示。 类的继承是单继承,接口的继承是多继承。

5、实现关系,一个类(class)实现一个或者多个接口(interface),表示具备某个能力。 实现是类和接口的常见关系,Java 中使用 implements 关键字表示。

6、在架构设计阶段时候,功能设计基本上是基于接口的,要定义出具体的接口和其功能。而在具体实现时候,可以采用抽象类来完成通用的实现。以及在后续的项目重构时候,可以采用添加抽象类。