abstract class
Java
中允许使用abstract
修饰符声明方法,此时只定义方法但是不实现方法(abstract
修饰的方法没有主体,只有一个签名和一个分号).
以下是abstract
方法和这些方法所在的abstract
类相关的规则:
- 只要类中有一个
abstract
方法,那么这个类本身就自动成为abstract
,而且必须声明为abstract class
,否则会导致编译错误; abstract class
无法实例化;abstract
类的子类必须覆盖超类的每个abstract
方法,并且把这些方法全部实现(即提供方法主体),才能实例化.这种类一般称为具体子类(concrete subclass
),目的是强调它不是抽象类.- 如果
abstract class
的子类没有实现集成的所有abstract
方法,那么这个子类仍然是abstract class
,而且必须使用abstract
声明; - 使用
static
,private
以及final
声明的方法不能是抽象方法,因为这三种方法在子类中不能被覆盖.类似的,final class
中不能有任何abstract
方法; - 就算类中没有
abstract
方法,这个类也能声明为abstract
.使用这种方法声明的abstract
类表明类实现的不完善,需要交给子类实现,这种类不能被实例化.
interface
Java
的类继承是单继承模式,为了更进一步的面向对象扩展,Java
创建了interface
概念.
interface
的作用只是描绘API
,因此,interface
提供类型的描述信息,以及实现这个API
的类应该提供的方法.
以下是interface
相关的规则:
interface
中所有强制方法都隐式使用abstract
声明,不能有方法主体,要使用分号(可以使用abstract
修饰符,不过一般省略);- 接口定义公开的
API
.interface
中的所有成员都隐式使用public
声明,而且习惯省略不必要的public
修饰符.如果在接口中使用protected
或者private
定义方法,会导致编译错误; interface
中不能定义任何势实例字段.字段是实现细节,而接口是规则不是事先,在接口中只能定义同时使用static
和final
声明的常量;- 接口不能实例化,因此不能定义构造函数;
- 接口中可能包含嵌套类型.嵌套类型隐式使用
public
和static
声明; - 从
Java 8
开始,interface
中可以包含静态方法.
区别总结
abstract class
与interface
存在诸多联系,也存在差异.
以下是个人总结的差异支出:
abstract class
是class
中存在未实现的方法,留待继承的子类实现,interface
中的方法则均是未实现的方法(Java 8
中interface
中的default
方法除外);
public interface List<E> extends Collection<E> {
// `interface`中被`default`修饰的方法,提供默认实现
default void sort(Comparator<? super E> c) {
Object[] a = this.toArray();
Arrays.sort(a, (Comparator) c);
ListIterator<E> i = this.listIterator();
for (Object e : a) {
i.next();
i.set((E) e);
}
}
}
- 子类只能
extends
单个abstract class
,但是可以implements
多个interface
; abstract class
中能声明non final
变量(诸如int test;
),interface
中仅能声明被static final
修饰的变量;abstract class
中变量可以被private
,public
以及protected
修饰,interface
中变量仅能被public
修饰;intercae
可以extends
多个interface
,而abstract class
可以extends
一个类(非限定于abstract class
)以及多个interface
.
编码使用
在日常的代码编写工作中,选用abstract class
或者interface
需要慎重.
abstract class
表示继承关系,继承关系在本质上是"is a"关系;interface
则表示具有某种行为关系,是like a
关系.
以带报警器的门
为例,她具有门的作用,也具有报警功能.
- 继承门(门为
abstract class
,子类实现开关函数); - 实现告警功能(实现告警
interface
,完成报警函数).
PS:
如果您觉得我的文章对您有帮助,请关注我的微信公众号,谢谢!