相同点:
(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)抽象类可以有构造器,接口没有构造器。