京东一面,美团一面都有问到,好好整理一下
常见问题,
抽象类只能包含抽象方法吗?抽象类能继承别的类吗?抽象类能实现接口吗?
接口能继承接口吗?抽象类和接口中的方法能被实现吗?
共同点:
都不能被实例化。
都可以包含抽象方法。(接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。)
都可以有默认实现的方法(Java 8 可以用 default 关键字在接口中定义默认方法)。
区别:
接口主要用于对类的行为进行约束,你实现了某个接口就具有了对应的行为。
抽象类主要用于代码复用,强调的是所属关系。
一个类只能继承一个类,但是可以实现多个接口。
接口中的成员变量只能是 public static final 类型的,不能被修改且必须有初始值,而抽象类的成员变量默认 default,可在子类中被重新定义,也可被重新赋值。
什么时候使用抽象类和接口?
- 如果拥有一些方法并且想让它们中的一些有默认实现,那么使用抽象类吧。
- 如果想实现多重继承,那么必须使用接口。由于Java不支持多继承,子类不能够继承多个类,但可以实现多个接口。因此就可以使用接口来解决它。
- 如果基本功能在不断改变,那么就需要使用抽象类。如果不断改变基本功能并且使用接口,那么就需要改变所有实现了该接口的类。
接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约。而抽象类在代码实现方面发挥作用,可以实现代码的重用,例如,模板方法设计模式是抽象类的一个典型应用,假设某个项目的所有HTTP请求都要用相同的方式进行权限判断、访问日志记录和异常处理,那么就可以定义一个抽象的基类,让所有的controller都继承这个抽象基类,在抽象基类的service方法中实现上述功能,在各个子类中只是完成各自的业务逻辑代码,伪代码如下:
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public abstract class BaseServlet extends HttpServlet {
public final void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
// 记录访问日志
// 进行权限判断
}
protected abstract void doService(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException;
// 注意访问权限定义成protected,显得既专业,又严谨,因为它是专门给子类用的
}
class MyServlet1 extends BaseServlet {
protected void doService(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
// 本Servlet只处理的具体业务逻辑代码
}
}