大厂面试官今天问我:“Java 接口和抽象类有什么区别?”这不张口就来?

学习分享,共勉

这里是小编拿到的学习资源,其中包括“中高级Java开发面试高频考点题笔记300道.pdf”和“Java核心知识体系笔记.pdf”文件分享,内容丰富,囊括了JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等大量知识点。同时还有Java进阶学习的知识笔记脑图(内含大量学习笔记)!

资料整理不易,读者朋友可以转发分享下!

Java核心知识体系笔记.pdf

记一次蚂蚁金服Java研发岗的面试经历,分享下我的复习笔记面经

中高级Java开发面试高频考点题笔记300道.pdf

记一次蚂蚁金服Java研发岗的面试经历,分享下我的复习笔记面经

架构进阶面试专题及架构学习笔记脑图

记一次蚂蚁金服Java研发岗的面试经历,分享下我的复习笔记面经

Java架构进阶学习视频分享

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

public FileLogger(String name, boolean enabled, Level minPermittedLevel, String filePath) throws IOException {

super(name, enabled, minPermittedLevel);

this.fileWriter = new FileWriter(filePath);

}

@Override

protected void doLog(Level level, String message) {

// 格式化level 和 message,输出到日志文件

fileWriter.write(…);

}

}

MessageQueuLogger

import java.util.logging.Level;

/**

  • 抽象类Logger的子类:输出日志到消息队列中

  • @author yanliang

  • @date 9/28/2020 6:39 PM

*/

public class MessageQueueLogger extends Logger {

private MessageQueueClient messageQueueClient;

public MessageQueueLogger(String name, boolean enabled, Level minPermittedLevel, MessageQueueClient messageQueueClient) {

super(name, enabled, minPermittedLevel);

this.messageQueueClient = messageQueueClient;

}

@Override

protected void doLog(Level level, String message) {

// 格式化level 和 message,输出到消息队列中

messageQueueClient.send(…)

}

}

通过上面的例子,我们来看下抽象类有哪些特性。

  • 抽象类不能被实例化,只能被继承。(new 一个抽象类,会报编译错误)

  • 抽象类可以包含属性和方法。方法既可以包含实现,也可以不包含实现。不包含实现的方法叫做抽象方法

  • 子类继承抽象类,必须实现抽象类中的所有抽象方法。

接口


同样的,下面我们通过一个例子来看下接口的使用场景。

/**

  • 过滤器接口

  • @author yanliang

  • @date 9/28/2020 6:46 PM

*/

public interface Filter {

void doFilter(RpcRequest req) throws RpcException;

}

/**

  • 接口实现类:鉴权过滤器

  • @author yanliang

  • @date 9/28/2020 6:48 PM

*/

public class AuthencationFilter implements Filter {

@Override

public void doFilter(RpcRequest req) throws RpcException {

// 鉴权逻辑

}

}

/**

  • 接口实现类:限流过滤器

  • @author yanliang

  • @date 9/28/2020 6:48 PM

*/

public class RateLimitFilter implements Filter{

@Override

public void doFilter(RpcRequest req) throws RpcException {

// 限流逻辑

}

}

/**

  • 过滤器使用demo

  • @author yanliang

  • @date 9/28/2020 6:48 PM

*/

public class Application {

// 过滤器列表

private List filters = new ArrayList<>();

filters.add(new AuthencationFilter());

filters.add(new RateLimitFilter());

public void handleRpcRequest(RpcRequest req) {

try {

for (Filter filter : filters) {

filter.doFilter(req);

}

} catch (RpcException e) {

// 处理过滤结果

}

// …

}

}

上面的案例是一个典型的接口使用场景。通过Java中的 interface 关键字定义了一个Filter 接口,AuthencationFilter 和 RetaLimitFilter 是接口的两个实现类,分别实现了对Rpc请求的鉴权和限流的过滤功能。

下面我们来看下接口的特性:

  • 接口不能包含属性(也就是成员变量)

  • 接口只能生命方法,方法不能包含代码实现

  • 类实现接口时,必须实现接口中生命的所有方法。

综上,从语法上对比,这两者有比较大的区别,比如抽象类中可以定义属性、方法的实现,而接口中不能定义属性,方法也不能包含实现等。

除了语法特性的不同外,从设计的角度,这两者也有较大区别。抽象类本质上就是类,只不过是一种特殊的类,这种类不能被实例化,只能被子类继承。属于is-a的关系。接口则是 has-a 的关系,表示具有某些功能。对于接口,有一个更形象的叫法:协议(contract)

抽象类和接口解决了什么问题?

=============================================================================

下面我们先来思考一个问题~

抽象类的存在意义是为了解决代码复用的问题(多个子类可以继承抽象类中定义的属性哈方法,避免在子类中,重复编写相同的代码)。

那么,既然继承本身就能达到代码复用的目的,而且继承也不一定非要求是抽象类。我们不适用抽象类,貌似也可以实现继承和复用。从这个角度上讲,我们好像并不需要抽象类这种语法呀。那抽象类除了解决代码复用的问题,还有其他存在的意义吗?

这里大家可以先思考一下哈~

我们还是借用上面Logger的例子,首先对上面的案例实现做一些改造。在改造之后的实现中,Logger不再是抽象类,只是一个普通的父类,删除了Logger中的两个方法,新增了 isLoggable()方法。FileLogger 和 MessageQueueLogger 还是继承Logger父类已达到代码复用的目的。具体代码如下:

/**

  • 父类:非抽象类,就是普通的类

  • @author yanliang

  • @date 9/27/2020 5:59 PM

*/

public class Logger {

private String name;

private boolean enabled;

private Level minPermittedLevel;

public Logger(String name, boolean enabled, Level minPermittedLevel) {

this.name = name;

this.enabled = enabled;

this.minPermittedLevel = minPermittedLevel;

}

public boolean isLoggable(Level level) {

return enabled && (minPermittedLevel.intValue() <= level.intValue());

}

}

/**

  • 抽象类Logger的子类:输出日志到文件中

  • @author yanliang

  • @date 9/28/2020 4:44 PM

*/

public class FileLogger extends Logger {

private Writer fileWriter;

public FileLogger(String name, boolean enabled, Level minPermittedLevel, String filePath) throws IOException {

super(name, enabled, minPermittedLevel);

this.fileWriter = new FileWriter(filePath);

}

protected void log(Level level, String message) {

if (!isLoggable(level)) return ;

// 格式化level 和 message,输出到日志文件

fileWriter.write(…);

}

}

package com.yanliang.note.java.abstract_demo;

import java.util.logging.Level;

/**

  • 抽象类Logger的子类:输出日志到消息队列中

  • @author yanliang

  • @date 9/28/2020 6:39 PM

*/

public class MessageQueueLogger extends Logger {

private MessageQueueClient messageQueueClient;

public MessageQueueLogger(String name, boolean enabled, Level minPermittedLevel, MessageQueueClient messageQueueClient) {

super(name, enabled, minPermittedLevel);

this.messageQueueClient = messageQueueClient;

}

protected void log(Level level, String message) {

if (!isLoggable(level)) return ;

// 格式化level 和 message,输出到消息队列中

messageQueueClient.send(…)

}

}

以上实现虽然达到了代码复用的目的(复用了父类中的属性),但是却无法使用多态的特性了。

像下面这样编写代码就会出现编译错误,因为Logger中并没有定义log()方法。

最后的话

无论是哪家公司,都很重视Spring框架技术,重视基础,所以千万别小看任何知识。面试是一个双向选择的过程,不要抱着畏惧的心态去面试,不利于自己的发挥。
同时看中的应该不止薪资,还要看你是不是真的喜欢这家公司,好了希望这篇文章对大家有帮助!

部分截图:
在这里插入图片描述

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

像下面这样编写代码就会出现编译错误,因为Logger中并没有定义log()方法。

最后的话

无论是哪家公司,都很重视Spring框架技术,重视基础,所以千万别小看任何知识。面试是一个双向选择的过程,不要抱着畏惧的心态去面试,不利于自己的发挥。
同时看中的应该不止薪资,还要看你是不是真的喜欢这家公司,好了希望这篇文章对大家有帮助!

部分截图:
[外链图片转存中…(img-Gf3dkLQV-1715530091060)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 18
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值