摘要:
抽象类和接口,都是用来抽象具体的,但是在层级维度上表示又是不同的,抽象类是用来抽象类别的,而接口是用来抽象具体功能的。在语法定义和使用上有相同点,但也存在一些差异。
抽象类和接口介绍
抽象类介绍
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、在架构设计阶段时候,功能设计基本上是基于接口的,要定义出具体的接口和其功能。而在具体实现时候,可以采用抽象类来完成通用的实现。以及在后续的项目重构时候,可以采用添加抽象类。