相同点:
(1)不能直接实例化。如果要实例化,抽象类变量必须实现所有抽象方法,接口变量必须实现所有接口未实现的方法。
(2)都可以有实现方法(Java8 以前的接口不能有实现方法)。
* @since 1.8
*/
default void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
final ListIterator<E> li = this.listIterator();
while (li.hasNext()) {
li.set(operator.apply(li.next()));
}
}
Java 1.8 新增了default关键字,可以使接口有自己的默认的实现类,而且还不影响接口的实现类。
(3)都可以不需要实现类或者继承者去实现所有方法(Java8 以前的接口,Java8 及以后的接口中可以包括默认方法,不需要实现者实现)。
public interface A {
default int c(){
return i;
}
int i = 0;
}
public class main {
public static void main(String[] args) {
A a = new A() {};
System.out.println(a.c());
}
}
不同点:
(1)抽象类和接口所反映出的设计理念不同。抽象类表示的是对象 / 类的抽象,接口表示的是对行为的抽象。
abstract class AbstractStudent{
abstract void study();
void sleep(){
System.out.println("sleep");
}
void smoke(){
System.out.println("抽烟");
}
}
//所有的Student被创建都会抽烟,是不是很搞笑?
class Student extends AbstractStudent{
Student Demo stu = new Student();
...
}
abstract class AbstractStudent{
abstract void study();
void sleep(){
System.out.println("sleep");
}
}
interface Smoking{
void smoke();
}
//普通的学生,继承AbstractStudent,有学习、睡觉的方法,不抽烟
class Student extends AbstractStudent{
(2)抽象类不可以多重继承,接口可以多重继承。即一个类只能继续一个抽象类,却可以继承多个接口。
(3)访问修饰符 ——
- 抽象类中的方法可以用 public protected 和 default abstract 修饰符,不能用 private、static、synchronize、native 修饰;变量可以在子类中重新定义,也可以重新赋值;
- 接口的方法默认修饰符是 public abstract, Java8 开始出现静态方法,多加 static 关键字;变量默认是 public static final 型,且必须给其初值,在实现类中也不能重新定义,也不能改变其值。
(4)抽象类可以有构造器,接口没有构造器。