SAP-ABAP:接口 vs 抽象类:ABAP OOP两类扩展方式的差异与选型原则


ABAP核心进阶篇(120篇):继承、多态与接口(12篇)

第七篇:接口 vs 抽象类:ABAP OOP两类扩展方式的差异与选型原则

博客标题:《接口 vs 抽象类:ABAP OOP两类扩展方式的差异与选型原则》

博客简介:系统对比接口与抽象类的语法特性、适用场景差异,结合"多能力实现"与"层级模板复用"两类典型业务需求,给出明确的选型判断标准,梳理混淆接口与抽象类使用的常见设计失误与优化方案。

📖 写在前面

在ABAP面向对象编程中,接口(Interface)抽象类(Abstract Class) 是实现代码扩展和多态的两种核心方式。很多开发者在实际项目中容易混淆这两种方式的适用场景,导致设计不合理、代码难以维护。

核心区别
#mermaid-svg-VpDdfjDpPJ2E71fN{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-VpDdfjDpPJ2E71fN .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-VpDdfjDpPJ2E71fN .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-VpDdfjDpPJ2E71fN .error-icon{fill:#552222;}#mermaid-svg-VpDdfjDpPJ2E71fN .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-VpDdfjDpPJ2E71fN .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-VpDdfjDpPJ2E71fN .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-VpDdfjDpPJ2E71fN .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-VpDdfjDpPJ2E71fN .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-VpDdfjDpPJ2E71fN .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-VpDdfjDpPJ2E71fN .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-VpDdfjDpPJ2E71fN .marker{fill:#333333;stroke:#333333;}#mermaid-svg-VpDdfjDpPJ2E71fN .marker.cross{stroke:#333333;}#mermaid-svg-VpDdfjDpPJ2E71fN svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-VpDdfjDpPJ2E71fN p{margin:0;}#mermaid-svg-VpDdfjDpPJ2E71fN .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-VpDdfjDpPJ2E71fN .cluster-label text{fill:#333;}#mermaid-svg-VpDdfjDpPJ2E71fN .cluster-label span{color:#333;}#mermaid-svg-VpDdfjDpPJ2E71fN .cluster-label span p{background-color:transparent;}#mermaid-svg-VpDdfjDpPJ2E71fN .label text,#mermaid-svg-VpDdfjDpPJ2E71fN span{fill:#333;color:#333;}#mermaid-svg-VpDdfjDpPJ2E71fN .node rect,#mermaid-svg-VpDdfjDpPJ2E71fN .node circle,#mermaid-svg-VpDdfjDpPJ2E71fN .node ellipse,#mermaid-svg-VpDdfjDpPJ2E71fN .node polygon,#mermaid-svg-VpDdfjDpPJ2E71fN .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-VpDdfjDpPJ2E71fN .rough-node .label text,#mermaid-svg-VpDdfjDpPJ2E71fN .node .label text,#mermaid-svg-VpDdfjDpPJ2E71fN .image-shape .label,#mermaid-svg-VpDdfjDpPJ2E71fN .icon-shape .label{text-anchor:middle;}#mermaid-svg-VpDdfjDpPJ2E71fN .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-VpDdfjDpPJ2E71fN .rough-node .label,#mermaid-svg-VpDdfjDpPJ2E71fN .node .label,#mermaid-svg-VpDdfjDpPJ2E71fN .image-shape .label,#mermaid-svg-VpDdfjDpPJ2E71fN .icon-shape .label{text-align:center;}#mermaid-svg-VpDdfjDpPJ2E71fN .node.clickable{cursor:pointer;}#mermaid-svg-VpDdfjDpPJ2E71fN .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-VpDdfjDpPJ2E71fN .arrowheadPath{fill:#333333;}#mermaid-svg-VpDdfjDpPJ2E71fN .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-VpDdfjDpPJ2E71fN .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-VpDdfjDpPJ2E71fN .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VpDdfjDpPJ2E71fN .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-VpDdfjDpPJ2E71fN .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VpDdfjDpPJ2E71fN .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-VpDdfjDpPJ2E71fN .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-VpDdfjDpPJ2E71fN .cluster text{fill:#333;}#mermaid-svg-VpDdfjDpPJ2E71fN .cluster span{color:#333;}#mermaid-svg-VpDdfjDpPJ2E71fN div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-VpDdfjDpPJ2E71fN .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-VpDdfjDpPJ2E71fN rect.text{fill:none;stroke-width:0;}#mermaid-svg-VpDdfjDpPJ2E71fN .icon-shape,#mermaid-svg-VpDdfjDpPJ2E71fN .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VpDdfjDpPJ2E71fN .icon-shape p,#mermaid-svg-VpDdfjDpPJ2E71fN .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-VpDdfjDpPJ2E71fN .icon-shape .label rect,#mermaid-svg-VpDdfjDpPJ2E71fN .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VpDdfjDpPJ2E71fN .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-VpDdfjDpPJ2E71fN .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-VpDdfjDpPJ2E71fN :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 面向对象扩展方式
接口
抽象类
定义'做什么'

(行为契约)
多重实现
能力组合
定义'怎么做'

(模板骨架)
单继承
代码复用

💡 一句话总结

  • 接口:定义"做什么"(What)------ 行为契约
  • 抽象类:定义"怎么做"(How)------ 模板骨架

本文将系统对比两者的语法特性、适用场景差异,给出明确的选型判断标准,并通过实际案例解析常见的设计失误与优化方案。

一、核心概念回顾

1.1 接口(Interface)

定义:接口是一种只声明方法签名、不提供具体实现的抽象类型。它定义了一组行为契约,由实现类来兑现。

特点 说明
🔹 只声明不实现 所有方法只有签名,没有代码体
🔹 成员全公开 所有成员默认为 PUBLIC
🔹 多重实现 一个类可以实现多个接口
🔹 仅常量和类型 不能包含变量(DATA),只能包含常量(CONSTANTS)和类型(TYPES
🔹 不可实例化 不能直接创建对象

代码示例

abap 复制代码
" ================================================================
" 接口定义
" ================================================================
INTERFACE zif_settlement
  PUBLIC.

  CONSTANTS: gc_success TYPE char1 VALUE 'S'.

  TYPES: BEGIN OF ty_order,
           order_id TYPE ebeln,
           amount   TYPE netwr,
           vendor   TYPE lifnr,
         END OF ty_order.

  METHODS: settle
    IMPORTING
      is_order TYPE ty_order
    RETURNING
      VALUE(rv_success) TYPE abap_bool.

  METHODS: validate
    IMPORTING
      is_order TYPE ty_order
    RETURNING
      VALUE(rv_valid) TYPE abap_bool.

ENDINTERFACE.

1.2 抽象类(Abstract Class)

定义:抽象类是包含抽象方法(未实现)和具体方法(已实现)的类。它不能被实例化,但可以为子类提供模板和默认实现。

特点 说明
🔶 含抽象方法 至少包含一个抽象方法(无实现)
🔶 也有具体方法 可包含已实现的具体方法,供子类复用
🔶 可含属性 支持完整的属性(DATA)、常量、类型
🔶 单继承 一个类只能继承一个抽象类
🔶 不可实例化 不能直接创建对象,需通过子类实例化

代码示例

abap 复制代码
" ================================================================
" 抽象类定义
" ================================================================
CLASS zcl_settlement DEFINITION ABSTRACT.

  PUBLIC SECTION.
    METHODS: settle ABSTRACT.             " 抽象方法(无实现)
    CONSTANTS: gc_success TYPE char1 VALUE 'S'.

  PROTECTED SECTION.
    DATA: amount TYPE netwr.               " 可包含属性
    METHODS: validate_order.               " 具体方法(有实现)

ENDCLASS.

CLASS zcl_settlement IMPLEMENTATION.
  METHOD validate_order.
    " ✅ 具体实现代码
    IF amount <= 0.
      WRITE: / '金额无效'.
    ENDIF.
  ENDMETHOD.
ENDCLASS.

二、全方位对比

2.1 核心语法对比表

维度 接口(Interface) 抽象类(Abstract Class)
定义关键字 INTERFACE CLASS ... DEFINITION ABSTRACT
方法实现 ❌ 只声明,不实现 ✅ 可含抽象方法 + 具体方法
成员可见性 全部为 PUBLIC 支持 PUBLIC/PROTECTED/PRIVATE
属性支持 ❌ 仅常量和类型 ✅ 完整属性支持
继承方式 类实现接口(INTERFACES 类继承类(INHERITING FROM
多重实现 ✅ 可实现多个 ❌ 只能单继承
实例化 ❌ 不可实例化 ❌ 不可实例化
方法调用 接口名~方法名 直接调用或 SUPER->方法名

2.2 代码实现方式对比

abap 复制代码
" ================================================================
" 🔷 类实现接口
" ================================================================
CLASS zcl_standard_settlement DEFINITION.
  PUBLIC SECTION.
    INTERFACES: zif_settlement.                    " 实现接口
ENDCLASS.

CLASS zcl_standard_settlement IMPLEMENTATION.
  METHOD zif_settlement~settle.                   " 方法名格式
    " 实现逻辑
  ENDMETHOD.
ENDCLASS.

" ================================================================
" 🔶 类继承抽象类
" ================================================================
CLASS zcl_standard_settlement DEFINITION
  INHERITING FROM zcl_settlement.                 " 继承抽象类
  PUBLIC SECTION.
    METHODS: settle REDEFINITION.                  " 重写抽象方法
ENDCLASS.

CLASS zcl_standard_settlement IMPLEMENTATION.
  METHOD settle.
    super->validate_order( ).                      " 调用父类具体方法
    " 实现逻辑
  ENDMETHOD.
ENDCLASS.

三、适用场景深度对比

3.1 接口适用场景

#mermaid-svg-8clcDRSVYHS0NyPL{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8clcDRSVYHS0NyPL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8clcDRSVYHS0NyPL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8clcDRSVYHS0NyPL .error-icon{fill:#552222;}#mermaid-svg-8clcDRSVYHS0NyPL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8clcDRSVYHS0NyPL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8clcDRSVYHS0NyPL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8clcDRSVYHS0NyPL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8clcDRSVYHS0NyPL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8clcDRSVYHS0NyPL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8clcDRSVYHS0NyPL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8clcDRSVYHS0NyPL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8clcDRSVYHS0NyPL .marker.cross{stroke:#333333;}#mermaid-svg-8clcDRSVYHS0NyPL svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8clcDRSVYHS0NyPL p{margin:0;}#mermaid-svg-8clcDRSVYHS0NyPL .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-8clcDRSVYHS0NyPL .cluster-label text{fill:#333;}#mermaid-svg-8clcDRSVYHS0NyPL .cluster-label span{color:#333;}#mermaid-svg-8clcDRSVYHS0NyPL .cluster-label span p{background-color:transparent;}#mermaid-svg-8clcDRSVYHS0NyPL .label text,#mermaid-svg-8clcDRSVYHS0NyPL span{fill:#333;color:#333;}#mermaid-svg-8clcDRSVYHS0NyPL .node rect,#mermaid-svg-8clcDRSVYHS0NyPL .node circle,#mermaid-svg-8clcDRSVYHS0NyPL .node ellipse,#mermaid-svg-8clcDRSVYHS0NyPL .node polygon,#mermaid-svg-8clcDRSVYHS0NyPL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8clcDRSVYHS0NyPL .rough-node .label text,#mermaid-svg-8clcDRSVYHS0NyPL .node .label text,#mermaid-svg-8clcDRSVYHS0NyPL .image-shape .label,#mermaid-svg-8clcDRSVYHS0NyPL .icon-shape .label{text-anchor:middle;}#mermaid-svg-8clcDRSVYHS0NyPL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8clcDRSVYHS0NyPL .rough-node .label,#mermaid-svg-8clcDRSVYHS0NyPL .node .label,#mermaid-svg-8clcDRSVYHS0NyPL .image-shape .label,#mermaid-svg-8clcDRSVYHS0NyPL .icon-shape .label{text-align:center;}#mermaid-svg-8clcDRSVYHS0NyPL .node.clickable{cursor:pointer;}#mermaid-svg-8clcDRSVYHS0NyPL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8clcDRSVYHS0NyPL .arrowheadPath{fill:#333333;}#mermaid-svg-8clcDRSVYHS0NyPL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8clcDRSVYHS0NyPL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8clcDRSVYHS0NyPL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8clcDRSVYHS0NyPL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8clcDRSVYHS0NyPL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8clcDRSVYHS0NyPL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8clcDRSVYHS0NyPL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8clcDRSVYHS0NyPL .cluster text{fill:#333;}#mermaid-svg-8clcDRSVYHS0NyPL .cluster span{color:#333;}#mermaid-svg-8clcDRSVYHS0NyPL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8clcDRSVYHS0NyPL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8clcDRSVYHS0NyPL rect.text{fill:none;stroke-width:0;}#mermaid-svg-8clcDRSVYHS0NyPL .icon-shape,#mermaid-svg-8clcDRSVYHS0NyPL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8clcDRSVYHS0NyPL .icon-shape p,#mermaid-svg-8clcDRSVYHS0NyPL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8clcDRSVYHS0NyPL .icon-shape .label rect,#mermaid-svg-8clcDRSVYHS0NyPL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8clcDRSVYHS0NyPL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8clcDRSVYHS0NyPL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8clcDRSVYHS0NyPL :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 接口适用场景
定义行为契约
能力组合
解耦调用方
跨模块交互

场景类型 说明 典型示例
行为契约 不同类需有相同的行为 结算、审批、导出
能力组合 一个类需具备多种能力 日志记录 + 权限校验 + 数据导出
解耦调用方 调用方只依赖接口,不依赖具体实现 策略模式、工厂模式
跨模块交互 不同模块间通过接口交互 模块间API定义

3.2 抽象类适用场景

#mermaid-svg-yZvah9W4Lguz2HEL{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-yZvah9W4Lguz2HEL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-yZvah9W4Lguz2HEL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-yZvah9W4Lguz2HEL .error-icon{fill:#552222;}#mermaid-svg-yZvah9W4Lguz2HEL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-yZvah9W4Lguz2HEL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-yZvah9W4Lguz2HEL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-yZvah9W4Lguz2HEL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-yZvah9W4Lguz2HEL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-yZvah9W4Lguz2HEL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-yZvah9W4Lguz2HEL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-yZvah9W4Lguz2HEL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-yZvah9W4Lguz2HEL .marker.cross{stroke:#333333;}#mermaid-svg-yZvah9W4Lguz2HEL svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-yZvah9W4Lguz2HEL p{margin:0;}#mermaid-svg-yZvah9W4Lguz2HEL .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-yZvah9W4Lguz2HEL .cluster-label text{fill:#333;}#mermaid-svg-yZvah9W4Lguz2HEL .cluster-label span{color:#333;}#mermaid-svg-yZvah9W4Lguz2HEL .cluster-label span p{background-color:transparent;}#mermaid-svg-yZvah9W4Lguz2HEL .label text,#mermaid-svg-yZvah9W4Lguz2HEL span{fill:#333;color:#333;}#mermaid-svg-yZvah9W4Lguz2HEL .node rect,#mermaid-svg-yZvah9W4Lguz2HEL .node circle,#mermaid-svg-yZvah9W4Lguz2HEL .node ellipse,#mermaid-svg-yZvah9W4Lguz2HEL .node polygon,#mermaid-svg-yZvah9W4Lguz2HEL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-yZvah9W4Lguz2HEL .rough-node .label text,#mermaid-svg-yZvah9W4Lguz2HEL .node .label text,#mermaid-svg-yZvah9W4Lguz2HEL .image-shape .label,#mermaid-svg-yZvah9W4Lguz2HEL .icon-shape .label{text-anchor:middle;}#mermaid-svg-yZvah9W4Lguz2HEL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-yZvah9W4Lguz2HEL .rough-node .label,#mermaid-svg-yZvah9W4Lguz2HEL .node .label,#mermaid-svg-yZvah9W4Lguz2HEL .image-shape .label,#mermaid-svg-yZvah9W4Lguz2HEL .icon-shape .label{text-align:center;}#mermaid-svg-yZvah9W4Lguz2HEL .node.clickable{cursor:pointer;}#mermaid-svg-yZvah9W4Lguz2HEL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-yZvah9W4Lguz2HEL .arrowheadPath{fill:#333333;}#mermaid-svg-yZvah9W4Lguz2HEL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-yZvah9W4Lguz2HEL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-yZvah9W4Lguz2HEL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yZvah9W4Lguz2HEL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-yZvah9W4Lguz2HEL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yZvah9W4Lguz2HEL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-yZvah9W4Lguz2HEL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-yZvah9W4Lguz2HEL .cluster text{fill:#333;}#mermaid-svg-yZvah9W4Lguz2HEL .cluster span{color:#333;}#mermaid-svg-yZvah9W4Lguz2HEL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-yZvah9W4Lguz2HEL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-yZvah9W4Lguz2HEL rect.text{fill:none;stroke-width:0;}#mermaid-svg-yZvah9W4Lguz2HEL .icon-shape,#mermaid-svg-yZvah9W4Lguz2HEL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yZvah9W4Lguz2HEL .icon-shape p,#mermaid-svg-yZvah9W4Lguz2HEL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-yZvah9W4Lguz2HEL .icon-shape .label rect,#mermaid-svg-yZvah9W4Lguz2HEL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yZvah9W4Lguz2HEL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-yZvah9W4Lguz2HEL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-yZvah9W4Lguz2HEL :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 抽象类适用场景
模板方法
代码复用
层级结构
强制实现

场景类型 说明 典型示例
模板方法 固定流程骨架,子类实现具体步骤 审批流程、结算流程
代码复用 多个子类共享共同逻辑 验证、状态更新
层级结构 表达"is-a"关系 采购订单是订单的一种
强制实现 通过抽象方法强制子类实现特定功能 确保子类完整性

3.3 典型业务场景选型指南

业务场景 推荐方式 选型理由
不同供应商接口对接 🔵 接口 统一契约,不同实现
不同类型订单结算 🔶 抽象类 共同流程 + 不同计算
日志记录功能 🔵 接口 能力组合,多个类需要
审批流程 🔶 抽象类 固定流程骨架
数据导出(Excel/PDF/CSV) 🔵 接口 统一接口,多种格式
权限校验功能 🔵 接口 能力组合
报表生成 🔶 抽象类 共同流程(查询→计算→展示)
消息通知(邮件/短信/推送) 🔵 接口 统一接口,多种方式

四、选型判断标准

4.1 选型决策流程图

#mermaid-svg-CqtforvtrXqEMxZx{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-CqtforvtrXqEMxZx .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-CqtforvtrXqEMxZx .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-CqtforvtrXqEMxZx .error-icon{fill:#552222;}#mermaid-svg-CqtforvtrXqEMxZx .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-CqtforvtrXqEMxZx .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-CqtforvtrXqEMxZx .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-CqtforvtrXqEMxZx .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-CqtforvtrXqEMxZx .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-CqtforvtrXqEMxZx .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-CqtforvtrXqEMxZx .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-CqtforvtrXqEMxZx .marker{fill:#333333;stroke:#333333;}#mermaid-svg-CqtforvtrXqEMxZx .marker.cross{stroke:#333333;}#mermaid-svg-CqtforvtrXqEMxZx svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-CqtforvtrXqEMxZx p{margin:0;}#mermaid-svg-CqtforvtrXqEMxZx .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-CqtforvtrXqEMxZx .cluster-label text{fill:#333;}#mermaid-svg-CqtforvtrXqEMxZx .cluster-label span{color:#333;}#mermaid-svg-CqtforvtrXqEMxZx .cluster-label span p{background-color:transparent;}#mermaid-svg-CqtforvtrXqEMxZx .label text,#mermaid-svg-CqtforvtrXqEMxZx span{fill:#333;color:#333;}#mermaid-svg-CqtforvtrXqEMxZx .node rect,#mermaid-svg-CqtforvtrXqEMxZx .node circle,#mermaid-svg-CqtforvtrXqEMxZx .node ellipse,#mermaid-svg-CqtforvtrXqEMxZx .node polygon,#mermaid-svg-CqtforvtrXqEMxZx .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-CqtforvtrXqEMxZx .rough-node .label text,#mermaid-svg-CqtforvtrXqEMxZx .node .label text,#mermaid-svg-CqtforvtrXqEMxZx .image-shape .label,#mermaid-svg-CqtforvtrXqEMxZx .icon-shape .label{text-anchor:middle;}#mermaid-svg-CqtforvtrXqEMxZx .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-CqtforvtrXqEMxZx .rough-node .label,#mermaid-svg-CqtforvtrXqEMxZx .node .label,#mermaid-svg-CqtforvtrXqEMxZx .image-shape .label,#mermaid-svg-CqtforvtrXqEMxZx .icon-shape .label{text-align:center;}#mermaid-svg-CqtforvtrXqEMxZx .node.clickable{cursor:pointer;}#mermaid-svg-CqtforvtrXqEMxZx .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-CqtforvtrXqEMxZx .arrowheadPath{fill:#333333;}#mermaid-svg-CqtforvtrXqEMxZx .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-CqtforvtrXqEMxZx .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-CqtforvtrXqEMxZx .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CqtforvtrXqEMxZx .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-CqtforvtrXqEMxZx .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CqtforvtrXqEMxZx .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-CqtforvtrXqEMxZx .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-CqtforvtrXqEMxZx .cluster text{fill:#333;}#mermaid-svg-CqtforvtrXqEMxZx .cluster span{color:#333;}#mermaid-svg-CqtforvtrXqEMxZx div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-CqtforvtrXqEMxZx .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-CqtforvtrXqEMxZx rect.text{fill:none;stroke-width:0;}#mermaid-svg-CqtforvtrXqEMxZx .icon-shape,#mermaid-svg-CqtforvtrXqEMxZx .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CqtforvtrXqEMxZx .icon-shape p,#mermaid-svg-CqtforvtrXqEMxZx .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-CqtforvtrXqEMxZx .icon-shape .label rect,#mermaid-svg-CqtforvtrXqEMxZx .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CqtforvtrXqEMxZx .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-CqtforvtrXqEMxZx .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-CqtforvtrXqEMxZx :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是







🎯 需要设计扩展点
需要代码复用?
需要共享属性

或具体方法?
表达 'is-a'

层级关系?
🔶 抽象类
需要多重实现?
🔵 接口
🔶 抽象类 或 🔵 接口

4.2 选型对照速查表

判断条件 ✅ 接口 ✅ 抽象类
需要代码复用
需要共享属性
需要多重实现
表达"is-a"关系
表达"has-a"能力
定义行为契约
强制子类实现
跨模块解耦

4.3 实际项目选型策略

#mermaid-svg-x7WNsggaC6DI7lBA{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-x7WNsggaC6DI7lBA .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-x7WNsggaC6DI7lBA .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-x7WNsggaC6DI7lBA .error-icon{fill:#552222;}#mermaid-svg-x7WNsggaC6DI7lBA .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-x7WNsggaC6DI7lBA .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-x7WNsggaC6DI7lBA .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-x7WNsggaC6DI7lBA .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-x7WNsggaC6DI7lBA .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-x7WNsggaC6DI7lBA .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-x7WNsggaC6DI7lBA .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-x7WNsggaC6DI7lBA .marker{fill:#333333;stroke:#333333;}#mermaid-svg-x7WNsggaC6DI7lBA .marker.cross{stroke:#333333;}#mermaid-svg-x7WNsggaC6DI7lBA svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-x7WNsggaC6DI7lBA p{margin:0;}#mermaid-svg-x7WNsggaC6DI7lBA .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-x7WNsggaC6DI7lBA .cluster-label text{fill:#333;}#mermaid-svg-x7WNsggaC6DI7lBA .cluster-label span{color:#333;}#mermaid-svg-x7WNsggaC6DI7lBA .cluster-label span p{background-color:transparent;}#mermaid-svg-x7WNsggaC6DI7lBA .label text,#mermaid-svg-x7WNsggaC6DI7lBA span{fill:#333;color:#333;}#mermaid-svg-x7WNsggaC6DI7lBA .node rect,#mermaid-svg-x7WNsggaC6DI7lBA .node circle,#mermaid-svg-x7WNsggaC6DI7lBA .node ellipse,#mermaid-svg-x7WNsggaC6DI7lBA .node polygon,#mermaid-svg-x7WNsggaC6DI7lBA .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-x7WNsggaC6DI7lBA .rough-node .label text,#mermaid-svg-x7WNsggaC6DI7lBA .node .label text,#mermaid-svg-x7WNsggaC6DI7lBA .image-shape .label,#mermaid-svg-x7WNsggaC6DI7lBA .icon-shape .label{text-anchor:middle;}#mermaid-svg-x7WNsggaC6DI7lBA .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-x7WNsggaC6DI7lBA .rough-node .label,#mermaid-svg-x7WNsggaC6DI7lBA .node .label,#mermaid-svg-x7WNsggaC6DI7lBA .image-shape .label,#mermaid-svg-x7WNsggaC6DI7lBA .icon-shape .label{text-align:center;}#mermaid-svg-x7WNsggaC6DI7lBA .node.clickable{cursor:pointer;}#mermaid-svg-x7WNsggaC6DI7lBA .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-x7WNsggaC6DI7lBA .arrowheadPath{fill:#333333;}#mermaid-svg-x7WNsggaC6DI7lBA .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-x7WNsggaC6DI7lBA .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-x7WNsggaC6DI7lBA .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-x7WNsggaC6DI7lBA .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-x7WNsggaC6DI7lBA .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-x7WNsggaC6DI7lBA .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-x7WNsggaC6DI7lBA .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-x7WNsggaC6DI7lBA .cluster text{fill:#333;}#mermaid-svg-x7WNsggaC6DI7lBA .cluster span{color:#333;}#mermaid-svg-x7WNsggaC6DI7lBA div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-x7WNsggaC6DI7lBA .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-x7WNsggaC6DI7lBA rect.text{fill:none;stroke-width:0;}#mermaid-svg-x7WNsggaC6DI7lBA .icon-shape,#mermaid-svg-x7WNsggaC6DI7lBA .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-x7WNsggaC6DI7lBA .icon-shape p,#mermaid-svg-x7WNsggaC6DI7lBA .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-x7WNsggaC6DI7lBA .icon-shape .label rect,#mermaid-svg-x7WNsggaC6DI7lBA .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-x7WNsggaC6DI7lBA .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-x7WNsggaC6DI7lBA .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-x7WNsggaC6DI7lBA :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 选型策略
策略一:接口优先
策略二:抽象类做模板
策略三:组合使用
不确定时优先用接口
更灵活,易于扩展
有明确流程模板时
定义骨架,子类实现步骤
接口定义契约
抽象类提供默认实现
子类按需扩展

五、接口 + 抽象类组合模式(最佳实践)

5.1 组合模式结构

#mermaid-svg-aIMLfLJo7JsKo7vk{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-aIMLfLJo7JsKo7vk .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-aIMLfLJo7JsKo7vk .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-aIMLfLJo7JsKo7vk .error-icon{fill:#552222;}#mermaid-svg-aIMLfLJo7JsKo7vk .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-aIMLfLJo7JsKo7vk .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-aIMLfLJo7JsKo7vk .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-aIMLfLJo7JsKo7vk .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-aIMLfLJo7JsKo7vk .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-aIMLfLJo7JsKo7vk .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-aIMLfLJo7JsKo7vk .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-aIMLfLJo7JsKo7vk .marker{fill:#333333;stroke:#333333;}#mermaid-svg-aIMLfLJo7JsKo7vk .marker.cross{stroke:#333333;}#mermaid-svg-aIMLfLJo7JsKo7vk svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-aIMLfLJo7JsKo7vk p{margin:0;}#mermaid-svg-aIMLfLJo7JsKo7vk .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-aIMLfLJo7JsKo7vk .cluster-label text{fill:#333;}#mermaid-svg-aIMLfLJo7JsKo7vk .cluster-label span{color:#333;}#mermaid-svg-aIMLfLJo7JsKo7vk .cluster-label span p{background-color:transparent;}#mermaid-svg-aIMLfLJo7JsKo7vk .label text,#mermaid-svg-aIMLfLJo7JsKo7vk span{fill:#333;color:#333;}#mermaid-svg-aIMLfLJo7JsKo7vk .node rect,#mermaid-svg-aIMLfLJo7JsKo7vk .node circle,#mermaid-svg-aIMLfLJo7JsKo7vk .node ellipse,#mermaid-svg-aIMLfLJo7JsKo7vk .node polygon,#mermaid-svg-aIMLfLJo7JsKo7vk .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-aIMLfLJo7JsKo7vk .rough-node .label text,#mermaid-svg-aIMLfLJo7JsKo7vk .node .label text,#mermaid-svg-aIMLfLJo7JsKo7vk .image-shape .label,#mermaid-svg-aIMLfLJo7JsKo7vk .icon-shape .label{text-anchor:middle;}#mermaid-svg-aIMLfLJo7JsKo7vk .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-aIMLfLJo7JsKo7vk .rough-node .label,#mermaid-svg-aIMLfLJo7JsKo7vk .node .label,#mermaid-svg-aIMLfLJo7JsKo7vk .image-shape .label,#mermaid-svg-aIMLfLJo7JsKo7vk .icon-shape .label{text-align:center;}#mermaid-svg-aIMLfLJo7JsKo7vk .node.clickable{cursor:pointer;}#mermaid-svg-aIMLfLJo7JsKo7vk .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-aIMLfLJo7JsKo7vk .arrowheadPath{fill:#333333;}#mermaid-svg-aIMLfLJo7JsKo7vk .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-aIMLfLJo7JsKo7vk .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-aIMLfLJo7JsKo7vk .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-aIMLfLJo7JsKo7vk .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-aIMLfLJo7JsKo7vk .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-aIMLfLJo7JsKo7vk .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-aIMLfLJo7JsKo7vk .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-aIMLfLJo7JsKo7vk .cluster text{fill:#333;}#mermaid-svg-aIMLfLJo7JsKo7vk .cluster span{color:#333;}#mermaid-svg-aIMLfLJo7JsKo7vk div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-aIMLfLJo7JsKo7vk .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-aIMLfLJo7JsKo7vk rect.text{fill:none;stroke-width:0;}#mermaid-svg-aIMLfLJo7JsKo7vk .icon-shape,#mermaid-svg-aIMLfLJo7JsKo7vk .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-aIMLfLJo7JsKo7vk .icon-shape p,#mermaid-svg-aIMLfLJo7JsKo7vk .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-aIMLfLJo7JsKo7vk .icon-shape .label rect,#mermaid-svg-aIMLfLJo7JsKo7vk .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-aIMLfLJo7JsKo7vk .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-aIMLfLJo7JsKo7vk .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-aIMLfLJo7JsKo7vk :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 📱 调用层
🟢 实现层
🔶 抽象层
🔵 接口层
继承
继承
继承
zif_settlement

定义行为契约
zcl_settlement_base

实现接口 + 提供默认实现
zcl_standard_settlement

标准订单
zcl_urgent_settlement

紧急订单
zcl_framework_settlement

框架订单
调用方(依赖接口类型)

5.2 完整代码实现

abap 复制代码
" ================================================================
" 🔵 第一步:接口定义契约
" ================================================================
INTERFACE zif_settlement
  PUBLIC.

  TYPES: BEGIN OF ty_order,
           order_id TYPE ebeln,
           amount   TYPE netwr,
           vendor   TYPE lifnr,
         END OF ty_order.

  METHODS: settle
    IMPORTING
      is_order TYPE ty_order
    RETURNING
      VALUE(rv_success) TYPE abap_bool.

  METHODS: validate
    IMPORTING
      is_order TYPE ty_order
    RETURNING
      VALUE(rv_valid) TYPE abap_bool.

ENDINTERFACE.

" ================================================================
" 🔶 第二步:抽象类提供默认实现
" ================================================================
CLASS zcl_settlement_base DEFINITION ABSTRACT.
  PUBLIC SECTION.
    INTERFACES: zif_settlement.

  PROTECTED SECTION.
    DATA: order_data TYPE zif_settlement=>ty_order.

    METHODS: validate_order
      RETURNING
        VALUE(rv_valid) TYPE abap_bool.

    METHODS: update_status.

    METHODS: calculate_amount ABSTRACT.   " 子类实现

ENDCLASS.

CLASS zcl_settlement_base IMPLEMENTATION.
  METHOD zif_settlement~settle.
    rv_success = abap_false.
    order_data = is_order.

    IF validate_order( ) = abap_false.
      RETURN.
    ENDIF.

    calculate_amount( ).      " 子类特有逻辑
    update_status( ).         " 共同逻辑

    rv_success = abap_true.
  ENDMETHOD.

  METHOD zif_settlement~validate.
    rv_valid = abap_true.
    IF order_data-order_id IS INITIAL OR
       order_data-amount <= 0 OR
       order_data-vendor IS INITIAL.
      rv_valid = abap_false.
    ENDIF.
  ENDMETHOD.

  METHOD update_status.
    WRITE: / '✅ 更新订单状态为已结算'.
  ENDMETHOD.
ENDCLASS.

" ================================================================
" 🟢 第三步:子类实现抽象方法
" ================================================================
CLASS zcl_standard_settlement DEFINITION
  INHERITING FROM zcl_settlement_base.
  PROTECTED SECTION.
    METHODS: calculate_amount.
ENDCLASS.

CLASS zcl_standard_settlement IMPLEMENTATION.
  METHOD calculate_amount.
    WRITE: / '📋 标准订单结算金额:', order_data-amount.
  ENDMETHOD.
ENDCLASS.

CLASS zcl_urgent_settlement DEFINITION
  INHERITING FROM zcl_settlement_base.
  PROTECTED SECTION.
    METHODS: calculate_amount.
ENDCLASS.

CLASS zcl_urgent_settlement IMPLEMENTATION.
  METHOD calculate_amount.
    WRITE: / '📋 紧急订单结算金额:', order_data-amount * 1.02.
  ENDMETHOD.
ENDCLASS.

" ================================================================
" 📱 第四步:调用方依赖接口
" ================================================================
DATA(lo_settlement) TYPE REF TO zif_settlement.

lo_settlement = NEW zcl_standard_settlement( ).
lo_settlement->settle( is_order = ls_order ).

lo_settlement = NEW zcl_urgent_settlement( ).
lo_settlement->settle( is_order = ls_order ).

六、常见设计失误与优化方案

6.1 失误一:用抽象类实现能力组合 ❌

#mermaid-svg-9hfBpb5SULVtnSG4{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-9hfBpb5SULVtnSG4 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-9hfBpb5SULVtnSG4 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-9hfBpb5SULVtnSG4 .error-icon{fill:#552222;}#mermaid-svg-9hfBpb5SULVtnSG4 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-9hfBpb5SULVtnSG4 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-9hfBpb5SULVtnSG4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-9hfBpb5SULVtnSG4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-9hfBpb5SULVtnSG4 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-9hfBpb5SULVtnSG4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-9hfBpb5SULVtnSG4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-9hfBpb5SULVtnSG4 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-9hfBpb5SULVtnSG4 .marker.cross{stroke:#333333;}#mermaid-svg-9hfBpb5SULVtnSG4 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-9hfBpb5SULVtnSG4 p{margin:0;}#mermaid-svg-9hfBpb5SULVtnSG4 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-9hfBpb5SULVtnSG4 .cluster-label text{fill:#333;}#mermaid-svg-9hfBpb5SULVtnSG4 .cluster-label span{color:#333;}#mermaid-svg-9hfBpb5SULVtnSG4 .cluster-label span p{background-color:transparent;}#mermaid-svg-9hfBpb5SULVtnSG4 .label text,#mermaid-svg-9hfBpb5SULVtnSG4 span{fill:#333;color:#333;}#mermaid-svg-9hfBpb5SULVtnSG4 .node rect,#mermaid-svg-9hfBpb5SULVtnSG4 .node circle,#mermaid-svg-9hfBpb5SULVtnSG4 .node ellipse,#mermaid-svg-9hfBpb5SULVtnSG4 .node polygon,#mermaid-svg-9hfBpb5SULVtnSG4 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-9hfBpb5SULVtnSG4 .rough-node .label text,#mermaid-svg-9hfBpb5SULVtnSG4 .node .label text,#mermaid-svg-9hfBpb5SULVtnSG4 .image-shape .label,#mermaid-svg-9hfBpb5SULVtnSG4 .icon-shape .label{text-anchor:middle;}#mermaid-svg-9hfBpb5SULVtnSG4 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-9hfBpb5SULVtnSG4 .rough-node .label,#mermaid-svg-9hfBpb5SULVtnSG4 .node .label,#mermaid-svg-9hfBpb5SULVtnSG4 .image-shape .label,#mermaid-svg-9hfBpb5SULVtnSG4 .icon-shape .label{text-align:center;}#mermaid-svg-9hfBpb5SULVtnSG4 .node.clickable{cursor:pointer;}#mermaid-svg-9hfBpb5SULVtnSG4 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-9hfBpb5SULVtnSG4 .arrowheadPath{fill:#333333;}#mermaid-svg-9hfBpb5SULVtnSG4 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-9hfBpb5SULVtnSG4 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-9hfBpb5SULVtnSG4 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9hfBpb5SULVtnSG4 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-9hfBpb5SULVtnSG4 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9hfBpb5SULVtnSG4 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-9hfBpb5SULVtnSG4 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-9hfBpb5SULVtnSG4 .cluster text{fill:#333;}#mermaid-svg-9hfBpb5SULVtnSG4 .cluster span{color:#333;}#mermaid-svg-9hfBpb5SULVtnSG4 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-9hfBpb5SULVtnSG4 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-9hfBpb5SULVtnSG4 rect.text{fill:none;stroke-width:0;}#mermaid-svg-9hfBpb5SULVtnSG4 .icon-shape,#mermaid-svg-9hfBpb5SULVtnSG4 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9hfBpb5SULVtnSG4 .icon-shape p,#mermaid-svg-9hfBpb5SULVtnSG4 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-9hfBpb5SULVtnSG4 .icon-shape .label rect,#mermaid-svg-9hfBpb5SULVtnSG4 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9hfBpb5SULVtnSG4 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-9hfBpb5SULVtnSG4 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-9hfBpb5SULVtnSG4 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} ❌ 错误
抽象类 A
抽象类 B
❌ 无法多重继承

abap 复制代码
" ❌ 错误:ABAP 不支持多重继承
CLASS zcl_logger DEFINITION ABSTRACT.
  METHODS: log.
ENDCLASS.

CLASS zcl_authorizer DEFINITION ABSTRACT.
  METHODS: authorize.
ENDCLASS.

CLASS zcl_business_service DEFINITION
  INHERITING FROM zcl_logger, zcl_authorizer.  " ❌ 编译错误
ENDCLASS.
abap 复制代码
" ✅ 正确:使用接口实现能力组合
INTERFACE zif_logger.
  METHODS: log.
ENDINTERFACE.

INTERFACE zif_authorizer.
  METHODS: authorize.
ENDINTERFACE.

CLASS zcl_business_service DEFINITION.
  PUBLIC SECTION.
    INTERFACES: zif_logger, zif_authorizer.   " ✅ 可实现多个接口
ENDCLASS.

6.2 失误二:用接口代替抽象类导致代码重复 ❌

#mermaid-svg-8EooveMHKQiBMvrX{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8EooveMHKQiBMvrX .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8EooveMHKQiBMvrX .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8EooveMHKQiBMvrX .error-icon{fill:#552222;}#mermaid-svg-8EooveMHKQiBMvrX .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8EooveMHKQiBMvrX .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8EooveMHKQiBMvrX .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8EooveMHKQiBMvrX .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8EooveMHKQiBMvrX .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8EooveMHKQiBMvrX .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8EooveMHKQiBMvrX .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8EooveMHKQiBMvrX .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8EooveMHKQiBMvrX .marker.cross{stroke:#333333;}#mermaid-svg-8EooveMHKQiBMvrX svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8EooveMHKQiBMvrX p{margin:0;}#mermaid-svg-8EooveMHKQiBMvrX .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-8EooveMHKQiBMvrX .cluster-label text{fill:#333;}#mermaid-svg-8EooveMHKQiBMvrX .cluster-label span{color:#333;}#mermaid-svg-8EooveMHKQiBMvrX .cluster-label span p{background-color:transparent;}#mermaid-svg-8EooveMHKQiBMvrX .label text,#mermaid-svg-8EooveMHKQiBMvrX span{fill:#333;color:#333;}#mermaid-svg-8EooveMHKQiBMvrX .node rect,#mermaid-svg-8EooveMHKQiBMvrX .node circle,#mermaid-svg-8EooveMHKQiBMvrX .node ellipse,#mermaid-svg-8EooveMHKQiBMvrX .node polygon,#mermaid-svg-8EooveMHKQiBMvrX .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8EooveMHKQiBMvrX .rough-node .label text,#mermaid-svg-8EooveMHKQiBMvrX .node .label text,#mermaid-svg-8EooveMHKQiBMvrX .image-shape .label,#mermaid-svg-8EooveMHKQiBMvrX .icon-shape .label{text-anchor:middle;}#mermaid-svg-8EooveMHKQiBMvrX .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8EooveMHKQiBMvrX .rough-node .label,#mermaid-svg-8EooveMHKQiBMvrX .node .label,#mermaid-svg-8EooveMHKQiBMvrX .image-shape .label,#mermaid-svg-8EooveMHKQiBMvrX .icon-shape .label{text-align:center;}#mermaid-svg-8EooveMHKQiBMvrX .node.clickable{cursor:pointer;}#mermaid-svg-8EooveMHKQiBMvrX .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8EooveMHKQiBMvrX .arrowheadPath{fill:#333333;}#mermaid-svg-8EooveMHKQiBMvrX .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8EooveMHKQiBMvrX .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8EooveMHKQiBMvrX .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8EooveMHKQiBMvrX .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8EooveMHKQiBMvrX .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8EooveMHKQiBMvrX .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8EooveMHKQiBMvrX .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8EooveMHKQiBMvrX .cluster text{fill:#333;}#mermaid-svg-8EooveMHKQiBMvrX .cluster span{color:#333;}#mermaid-svg-8EooveMHKQiBMvrX div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8EooveMHKQiBMvrX .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8EooveMHKQiBMvrX rect.text{fill:none;stroke-width:0;}#mermaid-svg-8EooveMHKQiBMvrX .icon-shape,#mermaid-svg-8EooveMHKQiBMvrX .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8EooveMHKQiBMvrX .icon-shape p,#mermaid-svg-8EooveMHKQiBMvrX .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8EooveMHKQiBMvrX .icon-shape .label rect,#mermaid-svg-8EooveMHKQiBMvrX .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8EooveMHKQiBMvrX .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8EooveMHKQiBMvrX .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8EooveMHKQiBMvrX :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 接口
实现类A
实现类B
实现类C
重复代码1
重复代码1
重复代码1

abap 复制代码
" ✅ 正确:抽象类提供默认实现
CLASS zcl_settlement_base DEFINITION ABSTRACT.
  PUBLIC SECTION.
    METHODS: settle ABSTRACT.
    METHODS: validate.           " ✅ 默认实现(只写一次)
    METHODS: update_status.      " ✅ 默认实现(只写一次)
ENDCLASS.

" 子类只需实现差异部分
CLASS zcl_standard_settlement DEFINITION
  INHERITING FROM zcl_settlement_base.
  PUBLIC SECTION.
    METHODS: settle REDEFINITION.
ENDCLASS.

6.3 失误三:接口定义过于宽泛 ❌

abap 复制代码
" ❌ 错误:接口职责过多
INTERFACE zif_business_object.
  METHODS: create, update, delete.   " CRUD
  METHODS: approve.                  " 审批(非必需)
  METHODS: settle.                   " 结算(非必需)
  METHODS: export.                   " 导出(非必需)
ENDINTERFACE.
abap 复制代码
" ✅ 正确:接口职责单一
INTERFACE zif_crud.          " 基础 CRUD
  METHODS: create, update, delete.
ENDINTERFACE.

INTERFACE zif_approveable.   " 可审批
  METHODS: approve.
ENDINTERFACE.

INTERFACE zif_settlement.    " 可结算
  METHODS: settle.
ENDINTERFACE.

" 采购订单 → 需要 CRUD + 审批 + 结算
CLASS zcl_purchase_order DEFINITION.
  PUBLIC SECTION.
    INTERFACES: zif_crud, zif_approveable, zif_settlement.
ENDCLASS.

" 物料主数据 → 只需要 CRUD
CLASS zcl_material DEFINITION.
  PUBLIC SECTION.
    INTERFACES: zif_crud.
ENDCLASS.

6.4 失误四:抽象类过度设计 ❌

abap 复制代码
" ❌ 错误:具体方法过多,子类难以扩展
CLASS zcl_report_generator DEFINITION ABSTRACT.
  PUBLIC SECTION.
    METHODS: generate_report.
  PROTECTED SECTION.
    METHODS: query_data.       " 具体实现
    METHODS: calculate.        " 具体实现
    METHODS: format_output.    " 具体实现
    METHODS: send_email.       " 具体实现
ENDCLASS.
abap 复制代码
" ✅ 正确:合理搭配抽象与具体方法
CLASS zcl_report_generator DEFINITION ABSTRACT.
  PUBLIC SECTION.
    METHODS: generate_report.              " 模板方法
  PROTECTED SECTION.
    METHODS: query_data ABSTRACT.          " 必须实现
    METHODS: calculate.                    " 默认实现,可重写
    METHODS: format_output ABSTRACT.       " 必须实现
    METHODS: send_email.                   " 默认实现
ENDCLASS.

七、快速参考卡片

接口 vs 抽象类速查表

维度 接口(Interface) 抽象类(Abstract Class)
定义关键字 INTERFACE CLASS ... ABSTRACT
方法实现 ❌ 只声明 ✅ 可含具体方法
属性支持 ❌ 仅常量 ✅ 完整属性
多重实现
适用场景 能力组合、解耦 代码复用、模板
选型口诀 定义"做什么" 定义"怎么做"

选型决策口诀

复制代码
🤔 不确定用哪个?记住三问:

1. 需要代码复用吗? → 需要 → 考虑抽象类
2. 需要多重能力吗? → 需要 → 使用接口
3. 既是又是怎么办? → 接口 + 抽象类 组合使用

八、总结

#mermaid-svg-R2uMwEbQYwEKetV5{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-R2uMwEbQYwEKetV5 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-R2uMwEbQYwEKetV5 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-R2uMwEbQYwEKetV5 .error-icon{fill:#552222;}#mermaid-svg-R2uMwEbQYwEKetV5 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-R2uMwEbQYwEKetV5 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-R2uMwEbQYwEKetV5 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-R2uMwEbQYwEKetV5 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-R2uMwEbQYwEKetV5 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-R2uMwEbQYwEKetV5 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-R2uMwEbQYwEKetV5 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-R2uMwEbQYwEKetV5 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-R2uMwEbQYwEKetV5 .marker.cross{stroke:#333333;}#mermaid-svg-R2uMwEbQYwEKetV5 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-R2uMwEbQYwEKetV5 p{margin:0;}#mermaid-svg-R2uMwEbQYwEKetV5 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-R2uMwEbQYwEKetV5 .cluster-label text{fill:#333;}#mermaid-svg-R2uMwEbQYwEKetV5 .cluster-label span{color:#333;}#mermaid-svg-R2uMwEbQYwEKetV5 .cluster-label span p{background-color:transparent;}#mermaid-svg-R2uMwEbQYwEKetV5 .label text,#mermaid-svg-R2uMwEbQYwEKetV5 span{fill:#333;color:#333;}#mermaid-svg-R2uMwEbQYwEKetV5 .node rect,#mermaid-svg-R2uMwEbQYwEKetV5 .node circle,#mermaid-svg-R2uMwEbQYwEKetV5 .node ellipse,#mermaid-svg-R2uMwEbQYwEKetV5 .node polygon,#mermaid-svg-R2uMwEbQYwEKetV5 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-R2uMwEbQYwEKetV5 .rough-node .label text,#mermaid-svg-R2uMwEbQYwEKetV5 .node .label text,#mermaid-svg-R2uMwEbQYwEKetV5 .image-shape .label,#mermaid-svg-R2uMwEbQYwEKetV5 .icon-shape .label{text-anchor:middle;}#mermaid-svg-R2uMwEbQYwEKetV5 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-R2uMwEbQYwEKetV5 .rough-node .label,#mermaid-svg-R2uMwEbQYwEKetV5 .node .label,#mermaid-svg-R2uMwEbQYwEKetV5 .image-shape .label,#mermaid-svg-R2uMwEbQYwEKetV5 .icon-shape .label{text-align:center;}#mermaid-svg-R2uMwEbQYwEKetV5 .node.clickable{cursor:pointer;}#mermaid-svg-R2uMwEbQYwEKetV5 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-R2uMwEbQYwEKetV5 .arrowheadPath{fill:#333333;}#mermaid-svg-R2uMwEbQYwEKetV5 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-R2uMwEbQYwEKetV5 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-R2uMwEbQYwEKetV5 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-R2uMwEbQYwEKetV5 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-R2uMwEbQYwEKetV5 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-R2uMwEbQYwEKetV5 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-R2uMwEbQYwEKetV5 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-R2uMwEbQYwEKetV5 .cluster text{fill:#333;}#mermaid-svg-R2uMwEbQYwEKetV5 .cluster span{color:#333;}#mermaid-svg-R2uMwEbQYwEKetV5 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-R2uMwEbQYwEKetV5 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-R2uMwEbQYwEKetV5 rect.text{fill:none;stroke-width:0;}#mermaid-svg-R2uMwEbQYwEKetV5 .icon-shape,#mermaid-svg-R2uMwEbQYwEKetV5 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-R2uMwEbQYwEKetV5 .icon-shape p,#mermaid-svg-R2uMwEbQYwEKetV5 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-R2uMwEbQYwEKetV5 .icon-shape .label rect,#mermaid-svg-R2uMwEbQYwEKetV5 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-R2uMwEbQYwEKetV5 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-R2uMwEbQYwEKetV5 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-R2uMwEbQYwEKetV5 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 扩展方式
🔵 接口
🔶 抽象类
✅ 多重实现
✅ 能力组合
✅ 解耦
✅ 代码复用
✅ 模板方法
✅ 共享属性
💡 最佳实践
接口定义契约
抽象类提供默认实现
子类按需扩展

维度 接口 抽象类
核心价值 定义行为契约、能力组合 代码复用、模板方法
继承方式 多重实现(INTERFACES 单继承(INHERITING FROM
属性支持 ❌ 仅常量和类型 ✅ 完整属性支持
方法实现 只声明 可含具体方法
适用场景 行为规范、能力组合、解耦 代码复用、模板方法、层级结构
灵活性 中等
选型口诀 定义"做什么" 定义"怎么做"

核心要点

  1. 接口 :定义"做什么"(What),支持多重实现,适合能力组合解耦
  2. 抽象类 :定义"怎么做"(How),提供默认实现,适合代码复用模板方法
  3. 组合使用:接口定义契约,抽象类提供默认实现,子类按需扩展
  4. 选型原则:需要代码复用/共享属性 → 抽象类;需要多重实现/解耦 → 接口

下一篇预告:《多态落地实战:基于接口的动态方法调用与业务逻辑解耦实现》

作者 :爱喝水的鱼丶

版本记录 :2026年7月

验证基准:SAP NetWeaver 7.51

💬 你在实际项目中遇到过接口和抽象类选型困难的场景吗?欢迎在评论区分享你的经验!

相关推荐
iCxhust1 小时前
linux目录是否保存在硬盘 启动后读入解析的
linux·运维·服务器
敖行客 Allthinker2 小时前
企业级多台服务器组装 K3s 高性能集群实战指南
运维·服务器·团队开发
TTBIGDATA3 小时前
【Ambari Plus】10.HBase 安装
大数据·运维·hadoop·ambari·hdp·cdh·bigtop
艾伦_耶格宇4 小时前
【ELK】-2 ELK的搭建
运维·elk
xcLeigh4 小时前
KES运维自动化与脚本体系实战
运维·数据库·自动化·脚本·数据迁移·kes
潘正翔4 小时前
docker基础_镜像使用
linux·运维·服务器·docker·容器·centos·devops
勉灬之4 小时前
利用双网卡服务器搭建 Verdaccio 中转,解决内网 npm 依赖下载问题
运维·服务器·npm
江湖有缘4 小时前
Lunalytics部署指南:使用Docker快速搭建私有监控面板
运维·docker·容器
DB哥讲数据库4 小时前
rocky linux安装教程:VMware虚拟机图文讲解部署Rocky Linux 9(附镜像包)
linux·运维·服务器