抽象类和接口的区别
看面试题经常看到这个,而且感觉记不住,有些回答也不是针对jdk8的。
jdk8:
default在接口中指的是显示指定的默认实现方法default方法,除接口之外指的都是没有写访问修饰符的,网上的说法叫默认default,也有叫友好的friendly。
1.类:抽象类是abstract class,接口是abstract interface(abstract是默认存在的,一般直接写interface)。
2.构造函数:抽象类可以有构造函数(访问修饰符可以任意,但是小于protected的话会造成子类有问题),接口不能有构造函数
3.属性:抽象类的属性的修饰符是可以任意的(private,默认,protected,public,static,非static,final,非final);而接口的属性只能用public static final修饰,并且默认就是public static final,只有这一种可能(写成static也是public static final的,而不是default static)。
4.方法:抽象类有抽象方法(不能有方法体),抽象方法不能是private(其他的可以);接口的所有方法只能是public并且默认也是public,没有方法体的抽象方法默认也是abstract修饰的,接口的方法若要有方法体则需要加上static或default(二选一,不能同时使用),子类调用时:static方法直接通过 接口名.方法名()使用,default方法还是通过 实现类的对象.方法名()。抽象类和接口都可以有main方法。
5.被使用:继承抽象类通过extends,但是抽象方法是default修饰的话,如果子类是在不同包中,那么会无法重写该方法,只能修饰实现类为abstract(但如果抽象类的所有构造函数的访问修饰符小于proected会造成实现类废掉——实现类的构造函数不能调用父类的构造函数);实现接口通过implements关键字,只能重写default方法和无实现的方法,不能重写接口的static方法。
抽象类除了abstract之外,其他都和普通类一样。
接口中的所有内容都是public的,也可以有static和default(此default是显示声明的,不是彼default)方法。
加深影响,再来一次:
抽象类是abstract class,接口是abstract interface。
抽象类的属性是任意修饰的,但是接口只能是public static final。
抽象类可以有构造函数,但是接口没有构造函数。
抽象类的可以有抽象方法(抽象方法只能是非private),接口所有的非static 和非default方法都是抽象方法(接口的所有方法只能是public),无论是抽象还是非抽象都只能是public方法)。抽象方法不可以是static静态的,无论接口还是抽象类。
抽象类和接口都必须被实现所有的抽象方法,但是实现类可以选择加上abstract关键字变成抽象类就可以不必实现所有方法。
如果要说下去:还有abstract不能和static,synchronized,native使用,抽象类中的方法可以有synchronized,native修饰,但是接口不行。等等,要是一个一个列出来,估计还是会有的。不过一通百通,自己总结总是更好的。
问一个问题:
之前讲过,如果test1包下有抽象类A的抽象方法a()是default修饰(也就是没有写访问修饰符),这个时候在外包test2包下写一个类B继承抽象类A,B必须实现A类的所有抽象方法,不然就只能也成为抽象类,因为default在外包下是不能被重写的,B也就成为了抽象类,那么这个时候如果又回到test1包下创建C类继承B类,那么C类能不能重写a()方法还是无法避免成为抽象类中的一份子呢?
揭晓答案:
package com.doubt.test1; public abstract class A { abstract void a(); }
package com.doubt.test2; import com.doubt.test1.A; public abstract class B extends A { }
package com.doubt.test1; import com.doubt.test2.B; public class C extends B { @Override void a() { System.out.println("aa"); } public static void main(String[] args) { C c = new C(); c.a(); } }
启动main方法后发现,控制台可以输出aa,但是这个写法IDEA本身是会报错的(C类中它会警告 “Method does not override method from its superclass”),是IDEA还不够强吗?
不过这种花里胡哨的写法只是好奇玩一玩,真的代码就别写了。