设计模式学习笔记 - 面向对象 - 5.接口和抽象类的区别

2024-02-27 1040阅读

温馨提示:这篇文章已超过394天没有更新,请注意相关的内容是否还可用!

简述

在面向对象编程中,抽象类和接口是常被用到的语法概念,是面向对象四大特性,以及很多设计模式、设计思想、设计原则实现的基础。它们之间的区别是什么?什么时候用接口?什么时候用抽象类?抽象类和接口存在的意义是什么?等等

设计模式学习笔记 - 面向对象 - 5.接口和抽象类的区别
(图片来源网络,侵删)

1.什么是抽象类和接口?它们有什么区别?

我们来看下 Java 语言中是如何定义抽象类的。下面这段代码是一个比较典型的抽象类的使用场景(模板方法模式)。Logger 是一个记录日志的抽象类,FileLogger 和 MessageQueueLogger 继承 Logger ,分别实现两种不同的日志记录方式:记录日志到文件和记录日志到消息队列。FileLogger 和 MessageQueueLogger 两个子类复用了父类 Logger 中的 name、enabled、minPermittedLevel 属性和 log() 方法,但是因为这两个子类的写日志方式不同,它们又各种重写了父类中的 doLog() 方法。

// 抽象类
public abstract 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 void log(Level level, String message) {
        boolean loggable = enabled && (minPermittedLevel.intValue() 
    private Writer fileWriter;
    public FileLogger(String name, boolean enabled,
                      Level minPermittedLevel, String filepath) {
        super(name, enabled, minPermittedLevel);
        this.fileWriter = new FileWriter(filepath);
    }
    @Override
    protected void doLog(Level level, String message) {
        // 格式化level和message,输出日志文件
        fileWriter.write(...);
    }
}
// 抽象的子类:输出日志到消息中间件(比如Kafka)
public class MessageQueueLogger extends Logger {
    private MessageQueueClient msgQueueClient;
    public MessageQueueLogger(String name, boolean enabled,
                              Level minPermittedLevel, MessageQueueClient msgQueueClient) {
        super(name, enabled, minPermittedLevel);
        this.msgQueueClient = msgQueueClient;
    }
    @Override
    protected void doLog(Level level, String message) {
        // 格式化level和message,输出到消息中间件
        msgQueueClient.send(...);
    }
}

    void doFilter(RpcRequest req) throws RpcException;
}
// 接口实现类:鉴权过滤器
public class AuthFilter implements Filter {
    @Override
    public void doFilter(RpcRequest req) throws RpcException {
        // 鉴权逻辑...
    }
}
// 接口实现类:限流过滤器
public class RateLimitFilter implements Filter {
    @Override
    public void doFilter(RpcRequest req) throws RpcException {
        // 限流逻辑...
    }
}
// 过滤器使用Demo
public class Application {
    private List
        try {
            for (Filter filter : filters) {
                filter.doFilter(req);
            }
        } catch (RpcException e) {
            // 处理过滤异常...
        }
        // 省略其他逻辑...
    }
}

    private String name;
    private boolean enabled;
    private Level minPermittedLevel;
    public Logger(String name, boolean enabled, Level minPermittedLevel) {
        //...构造函数不变,代码省略...
    }
    public boolean isLoggable(Level level) {
        boolean loggable = enabled && (minPermittedLevel.intValue() 
    private Writer fileWriter;
    public FileLogger(String name, boolean enabled,
                      Level minPermittedLevel, String filepath) {
        //...构造函数不变,代码省略...
    }
    public void log(Level level, String message) {
        if (!isLoggable(level)) return;
        // 格式化level和message,输出到日志文件
        fileWriter.write(...);
    }
}
// 子类: 输出日志到消息中间件(比如kafka)
public class MessageQueueLogger extends Logger {
    private MessageQueueClient msgQueueClient;
    public MessageQueueLogger(String name, boolean enabled,
                              Level minPermittedLevel, MessageQueueClient msgQueueClient) {
        //...构造函数不变,代码省略...
    }
    public void log(Level level, String message) {
        if (!isLoggable(level)) return;
        // 格式化level和message,输出到消息中间件
        msgQueueClient.send(...);
    }
}

    // 省略其他代码...
    public void log(Level level, String message) { //do nothing... }
}
public class FileLogger extends Logger {
    // 省略其他代码...
    @Override
    public void log(Level level, String message) {
        if (!isLoggable(level)) return;
        // 格式化level和message,输出到日志文件
        fileWriter.write(...);
    }
}
public class MessageQueueLogger extends Logger {
    // 省略其他代码...
    @Override
    public void log(Level level, String message) {
        if (!isLoggable(level)) return;
        // 格式化level和message,输出到消息中间件
        msgQueueClient.send(...);
    }
}
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]