接口与抽象类详解
一、 概念:
接口和抽象类的概念不一样。接口是对动作的抽象,抽象类是对根源的抽象。
抽象类表示的是,这个对象是什么。接口表示的是,这个对象能做什么。比如,男人,女人,这两个类(如果是类的话……),他们的抽象类是人。说明,他们都是人。
人可以吃东西,狗也可以吃东西,你可以把“吃东西”定义成一个接口,然后让这些类去实现它.
所以,在高级语言上,一个类只能继承一个类(抽象类)(正如人不可能同时是生物和非生物),但是可以实现多个接口(吃饭接口、走路接口)。
看到一个对概念描述很好的博客,借用一下,下面是该博客的链接
接口和抽象类的概念
二、区别
项目 | 关系 | 有无构造方法 | 特点 | 成员变量 | 成员方法 |
---|---|---|---|---|---|
接口 | like-a | 无 | 多继承多实现 | 只能是常量 | 全是抽象方法 |
抽象类 | is-a | 有 | 单继承 | 常量和变量 | 抽象和普通方法 |
三、详解
1 关系
like-a表示组合:接口是行为的抽象,是一种行为的规范,所以接口是like a 的关系;
is-a 表示继承:抽象是对类的抽象,是一种模板设计,所以抽象类是is a 的关系。
2有无构造方法
接口没有构造方法
抽象类有构造方法,一般用于给子类使用。
注意:接口和抽象类均不可以被实例化。
实例化和有没有构造方法没有关系,构造方法只是初始化对象的,new关键字向JVM申请内存来创建对象的。
It is a compile-time error if an attempt is made to create
an instance of an abstract class using a class instance creation expression.
A subclass of an abstract class that is not itself abstract may be instantiated,
resulting in the execution of a constructor for the abstract class and, therefore,
the execution of the field initializers for instance variables of that class.
大概意思就是:如果试图使用类实例创建表达式创建抽象类的实例,则为编译时错误。
抽象类的子类本身不是抽象的,可以实例化,从而执行抽象类的构造函数,从而执行该类实例变量的字段初始值设定项。
从内存角度来看:对象实例化的时候,关键字new向JVM申请内存,这个类的成员(成员变量,成员方法)会被保存到内存中。而抽象类,没有具体的成员(成员变量,成员方法),没办法准确分配内存。
3特点
接口支持多继承,一个接口可以继承多个接口,一个类可以同时实现多个接口。
类与类之间只能是单继承。
4成员变量
成员变量包括:类变量(static),实例变量和常量。
接口的成员变量的默认修饰符为: public static final ,且必须赋初值,不可改。
例: public static final int a = 1;虽然声明了变量a,但由于被final修饰,且已赋初值不可再赋值,所以相当于一个常量。所以其实现类可以直接使用接口的常量。
抽象类中成员变量默认修饰符 default,可在子类中被重新定义,也可被重新赋值。
5成员方法
接口所有的成员方法都是public abstract的。(都是抽象方法)
抽象类的抽象方法被abstract修饰,不能被private、static、synchronized和native等修饰,必须以分号结尾,不带花括号。
四、新增特性
关于接口
1、JDK1.8中对接口增加了新的特性:
(1)默认方法(default method):JDK 1.8允许给接口添加非抽象的方法实现,但必须使用default关键字修饰;定义了default的方法可以被实现子类所实现,也能被实现子类的对象调用;如果子类实现了多个接口,并且这些接口包含一样的默认方法,则子类必须重写默认方法;
(2)静态方法(static method):JDK 1.8中允许使用static关键字修饰一个方法,并提供实现,称为接口静态方法。接口静态方法只能通过接口调用(接口名.静态方法名)。
2、JDK 1.9时,接口中的方法可以是private的
关于抽象类
JDK 1.8时,抽象类的方法默认访问权限变为default