实施继承

学习目标

  • 实施专用类。

继承实施

观看此视频,了解一般课程和更专业课程的概念。

视频:本节含 SAP 官方视频(视频 ID 1_0v28hhn4),需在 learning.sap.com 在线观看。

继承 -"是 A"关系

在建模中,我们谈论的是专业化。在编程语言中实施此关系使用继承概念,在该概念中,新类(子类)派生自现有类(超类)。查看两个类之间是否存在真正的继承关系的可靠测试是尝试说"子类是超类"。如果这显然是真的,你就有了继承关系。如果显然不是真的,甚至听起来有点奇怪,你就没有继承关系,不应该实施 一个,因为这很可能会造成问题进一步下线。测试我们的车型时,我们绝对可以说"货机是飞机","客机是飞机"。

从超级类继承的类自动包含超级类的所有组件。例如,客机类具有制造商和类型,就像飞机一样。这应该并不奇怪,因为客机是飞机。最初出现的假冒是,客机类无法进入自己的制造商和类型。这是因为它们是超类的专用属性,因此子类无法访问它们。稍后,您将学习如何允许子类访问超类的组件,而无需将其完全公开。

定义继承关系

在 ABAP 中,使用类定义语句中的 INHERITING FROM 附加实施继承。在此示例中,客机类定义为平面类的子类。请注意,子类知道其超类,但飞机类不知道其具有哪些子类(如果有)。

子类只能有一个直接超级类。

一个超类 - 任意数量的子类

平面类可以具有任意数量的子类,但不了解其中任何一个子类。

每个子类都有一个直接超级类。它知道其超类,但不知道任何同级类(从同一超类派生的其他类)。在我们的示例中,客机类不了解货机类。

如何扩展子类

声明子类后,需要向其添加新组件或更改现有组件。这就是将飞机类的单纯副本变成客机或货机。由于继承,您无需从头实施类 - 只需通过它需要的新组件对其进行扩展。

有三种方法可以执行此操作:

添加新组件:可以在类中声明新属性、类型、常量和方法。其名称不得与已用于声明超类中组件的其它名称发生冲突。还必须确保新组件仅与子类相关,而与超级类的所有专用化无关。如果声明通常相关的新属性或方法,则必须将其移动到超级类中。

重新定义方法:调用继承方法时,运行时系统将从超级类执行方法的实施。但是,此实施无法考虑已在子类中声明的任何新组件。在这种情况下,可以重新定义方法。这意味着您可以为其分配与子类相关的新实施。

添加新的构造函数:构造函数确保正确初始化类的新实例。创建子类的实例时,运行时系统始终执行超级类的构造函数。例如,这可确保客机具有制造商和类型,方法与任何其他飞机相同。但是,超级类的构造函数无法初始化子类的属性,因为它不知道它们是否存在。因此,您可以为子类定义新的构造函数。

声明新组件

可通过声明新组件来扩展子类。它们对类本身可见,但对超类不可见,也不对从同一超类继承的任何其他类可见。因此,您需要考虑新组件是仅在当前类中相关,还是实际需要在父类中声明。

受保护组件

即使子类包含其超级类的所有属性,也不允许自己直接访问专用组件。有时这是必要的,但有时超级类需要让其子类访问特定属性或方法,而无需将其完全公开。它可以通过在受保护部分中声明来执行此操作。受保护组件在类本身内可见,但也对所有子类可见。

在类定义中,使用语句 PROTECTED SECTION 引入受保护部分。必须始终声明序列 PUBLIC SECTION - PROTECTED SECTION - PRIVATE SECTION 中的可见性部分。

您可以使用快速修复移动类的现有组件。为此,将光标放在 ADT 中的组件名称上,然后按 Ctrl + 1,然后选择快速修复使 受到保护

将私有组件移动到受保护部分是一项兼容的更改 - 您已扩展组件的可见性。但是,使公共组件受保护是不兼容的更改,可能会导致语法错误。这是因为您已限制组件的可见性,该组件可能已在继承层次结构之外使用。

重定义方法

超级类通常包含要在子类中使用的方法,但其实施不适合,因为它们不考虑子类的特定性质。例如,平面类的 get_attributes 方法不能返回在客机类中定义的属性。但是,客机类仍需要方法 get_attributes。

在 ABAP 中,可以通过重新定义实例方法 get_attributes 来解决此问题。重新定义方法时,在子类中为其编写一个新实施,该实施会考虑只有子类可以了解的内容。但是,方法的定义完全相同。您必须遵循以下规则:

  • 方法保留相同的名称。

  • 通过使用附加项 REDEFINITION 在子类中声明方法,指示要重新定义方法。

  • 该方法与超类中的可见性相同。

  • 不得更改方法的签名。

无法重新定义静态方法。

实施重新定义

实施方法的重新定义时,可以在超级类中调用实施。使用隐式对象参考 super 执行此操作,该超级参考指向当前实例中的父类。通过这种方式,您可以重用超级类中的方法实施,然后在自己的实施中将其添加到该父类中。

无需声明参考变量 super。它在重新定义的方法实施中自动可用。

以这种方式调用父类中的方法是可选的。有时会是个好主意,有时也没有什么可以得到的。

新建构造函数定义

在子类中,可以定义新的构造函数。与方法重新定义相反,构造函数可能具有自己的签名。构造函数的签名通常包含与超级类的构造函数相同的参数,以及其自身的新参数。这是因为新实例构造函数有两个任务 - 首先调用超级类的构造函数,然后负责初始化特定于子类的自有属性。

除了定义新构造函数外,还可以在子类中定义新的静态构造函数。

构造函数的角色

子类的构造函数有两个函数:它必须确保父类的组件正确初始化,然后可以设置子类属性的初始值。

在我们的示例中,由于客机是飞机,因此除非飞机类的构造函数已成功运行以设置新客机的制造商和类型,否则不能有客机实例。只有这样,客机类才能设置自己的属性。

因此,子类的构造函数不仅必须能够设置其自己的属性,而且能够将所需值传递给超级类的构造函数。因此,子类中构造函数的签名通常包含调用所需的构造函数的整个签名。

新构造函数实施的顺序

在新构造函数的实现中,有一个必须观察的特定操作序列。最重要的事件是对超级类构造函数的调用。这是强制性的,您可以使用隐式参考超级调用方法,就像调用重新定义的方法的原始实施时一样。同样,您也不需要明确声明 super。

调用超级类的构造函数之前,不得处理正在构建的实例的任何实例组件。您可以处理类的静态组件,并检查构造函数导入参数的正确性。如果不正确,则引发异常。

超级类的构造函数成功运行后,您可以处理新实例的实例组件。

构造函数调用序列

该图说明了调用静态和实例构造函数的顺序。该示例假设程序想要实例化客机类,并且该平面类之前尚未寻址。

当程序尝试创建客平面类的实例时,运行时系统会从继承层次结构的顶部开始按顺序自动调用静态构造函数。运行完所有静态构造函数后,运行时系统将调用子类的实例构造函数,该子类又会调用超级类的实例构造函数。

试用:继承实施

  1. 创建实施接口 IF_OO_ADT_CLASSRUN 的新类。

  2. 切换到 局部类型 标签并将以下代码片段复制到编辑器中:

CLASS lcl_plane DEFINITION.
PUBLIC SECTION.
TYPES: BEGIN OF ts_attributes,
name TYPE string,
value TYPE string,
END OF ts_attributes,
* declare table - do not allow the same attribute to be used more than once
tt_attributes TYPE SORTED TABLE OF ts_attributes WITH UNIQUE KEY name.
METHODS constructor IMPORTING iv_manufacturer TYPE string
iv_type TYPE string.
METHODS: get_Attributes RETURNING VALUE(rt_Attributes) TYPE tt_attributes.
PROTECTED SECTION.
DATA manufacturer TYPE string.
DATA type TYPE string.
PRIVATE SECTION.
ENDCLASS.
CLASS lcl_plane IMPLEMENTATION.
METHOD constructor.
manufacturer = iv_manufacturer.
type = iv_type.
ENDMETHOD.
METHOD get_attributes.
rt_attributes = VALUE #( ( name = 'MANUFACTURER' value = manufacturer )
( name = 'TYPE' value = type ) ) .
ENDMETHOD.
ENDCLASS.
CLASS lcl_cargo_plane DEFINITION INHERITING FROM lcl_plane.
PUBLIC SECTION.
METHODS constructor IMPORTING iv_manufacturer TYPE string
iv_type TYPE string
iv_cargo TYPE i.
METHODS get_attributes REDEFINITION.
private section.
data cargo type i.
ENDCLASS.
CLASS lcl_cargo_plane IMPLEMENTATION.
METHOD constructor.
super->constructor( iv_manufacturer = iv_manufacturer iv_type = iv_type ).
cargo = iv_cargo.
ENDMETHOD.
METHOD get_attributes.
* method uses protected attributes of superclass
rt_attributes = value #( ( name = 'MANUFACTURER' value = manufacturer )
( name = 'TYPE' value = type )
( name ='CARGO' value = cargo ) ).
ENDMETHOD.
ENDCLASS.
CLASS lcl_passenger_plane DEFINITION INHERITING FROM lcl_Plane.
PUBLIC SECTION.
METHODS constructor IMPORTING iv_manufacturer TYPE string
iv_type TYPE string
iv_seats TYPE i.
METHODS get_Attributes REDEFINITION.
private section.
data seats type i.
ENDCLASS.
CLASS lcl_passenger_plane IMPLEMENTATION.
METHOD constructor.
super->constructor( iv_manufacturer = iv_manufacturer iv_type = iv_type ).
ENDMETHOD.
METHOD get_attributes.
* Redefinition uses call of superclass implementation
rt_attributes = super->get_attributes( ).
rt_Attributes = value #( base rt_attributes ( name = 'SEATS' value = seats ) ).
ENDMETHOD.
ENDCLASS.
  1. 按 Ctrl + F3 激活类。

  2. 通过使用 F2 文档和导航功能等编辑器功能熟悉源代码。

注意

此示例中没有可执行代码。

使用抽象组件和最终组件

可将类声明为抽象。这意味着程序无法对其进行实例化。在我们的示例中,对于飞机、客机和货机,您可以决定在实际中,只有客机和货机。但是,从软件建模的角度来看,让类 lcl_plane 来容纳货物飞机和客机共有的组件是非常有用的。通过使用抽象类,您可以实现平面类中的所有公用组件,而无需担心有人可能会错误地创建类的实例。

如果类是抽象类,您仍然可以访问其静态组件。具体包括:

  • 静态方法

  • 静态属性

  • 常量

  • 类型定义

尽管您可以实现抽象类的方法,但也可以将单个方法声明为抽象。在这种情况下,声明它的类中没有其实施。请注意,只能在抽象类中声明抽象方法。

只有重新定义抽象方法后,才能实例化抽象类的子类。

您可以将类声明为 FINAL。这意味着它不能有任何子类。

在本身不是最终的类中,可以将方法声明为最终方法。这意味着,尽管类本身可能具有子类,但方法本身无法重新定义。如果方法包含权限检查,则可以执行此操作。否则,子类可能会重新定义方法并忽略权限检查。

实施继承

您注意到本地类 LCL_PASSENGER_FLIGHTLCL_CARGO_FLIGHT 有很多共同之处,并且包含冗余实施。从模型的角度来看,您可以将乘客航班和货物航班视为航班的两种专业领域。因此,引入具有通用定义和实施的通用超类 LCL_FLIGHT

模板:

  • /LRN/CL_S4D401_ACS_AUTH_CHECK(全局类)

解决方案:

  • /LRN/CL_S4D401_OOS_INHERITANCE(全局类)

任务 1: 复制模板(可选)

复制模板类 /LRN/CL_S4D401_ACS_AUTH_CHECK。如果已完成上一练习,则可以跳过此任务并继续编辑类 ZCL_##_SOLUTION

步骤

  1. 将类 /LRN/CL_S4D401_ACS_AUTH_CHECK 复制到您自己的包中的类(建议名称:ZCL_##_SOLUTION,其中 ## 代表组编号)。

  2. 在项目浏览器中,右键单击类 /LRN/CL_S4D401_ACS_AUTH_CHECK 以打开上下文菜单。

  3. 从上下文菜单中,选择复制....

  4. 在包字段中输入的名称。在名称字段中,输入 ZCL_##_SOLUTION,其中 ## 代表组编号。

  5. 选择下一步

  6. 确认传输请求并选择完成

  7. 激活复制。

  8. Ctrl + F3 激活类。

任务 2: 定义超类

定义一个新的局部类 LCL_FLIGHT,并让局部类 LCL_PASSENGER_FLIGHTLCL_CARGO_FLIGHT 继承自该类。比较这两个子类,并将两个类中相同的属性和方法定义移动到父类。

步骤

  1. 在全局类 ZCL_##_SOLUTION 中,使用代码模板定义新的本地类 LCL_FLIGHT

注意

确保在局部类型标签上定义源代码开头的新类,以便可以在现有局部类中引用该类。

  1. 在全局类 ZCL_##_SOLUTION 中,切换到局部类型标签。

  2. 在源代码开头,键入 lcl 并按 **Ctrl + 空格**键以调用代码完整化。

  3. 从建议的完成清单中,选择 lcl - Local class

  4. lcl_ 仍突出显示时,输入 lcl_flight 调整定义和实施部分中的类名称。

  5. 代码模板应已添加以下代码:

CLASS lcl_flight DEFINITION CREATE PRIVATE.
PUBLIC SECTION.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS lcl_flight IMPLEMENTATION.
ENDCLASS.
  1. 确保无法创建 LCL_FLIGHT 的实例。

  2. 移除 CREATE PRIVATE 附加并将其替换为 ABSTRACT 附加项。

  3. 确保您的代码如下所示:

*  CLASS lcl_flight DEFINITION CREATE PRIVATE.
CLASS lcl_flight DEFINITION ABSTRACT.
  1. 允许本地类 LCL_PASSENGER_FLIGHT 从本地类 LCL_FLIGHT 继承。

  2. 向下滚动至本地类 LCL_PASSENGER_FLIGHT 的定义部分。

  3. 如下调整代码:

CLASS lcl_passenger_flight DEFINITION
INHERITING FROM lcl_flight.
  1. 通过在子类 LCL_PASSENGER_FLIGHT 中方法 CONSTRUCTOR 的实施开始时添加 super->constructor( ).,修复语法错误*"在构造函数方法中,只有在调用超类……的构造函数后才能访问实例属性..."*。

注意

我们稍后将在本练习中详细介绍构造函数逻辑。

  1. 如下调整代码:

METHOD constructor.
super->constructor(  ).
  1. 使用快速修复将以下公共组件从子类 LCL_PASSENGER_FLIGHT 移动("拉出")到超类 LCL_FLIGHT

  • 属性 carrier_id

  • 属性 connection_id

  • 属性 flight_date

  • 结构类型 ST_CONNECTION_DETAILS

  • 方法 GET_CONNECTION_DETAILS

注意

此步骤导致在移动的 GET_CONNECTION_DETAILS 方法的实施中出现语法错误,因为它访问在超类 LCL_FLIGHT 中尚不可用的组件。将在下一步中修复此错误。

  1. 在本地类 LCL_PASSENGER_FLIGHT 的定义部分中,将光标放在 carrier_id 上并选择 Ctrl + 1 以显示可用快速修复的列表。

  2. 从可用快速修复列表中,选择 Pull-Up carrier_id 以超类 lcl_flight

  3. 对上面列出的其他组件重复此操作。

  4. 超级类 LCL_FLIGHT 的定义部分现在应如下所示:

CLASS lcl_flight DEFINITION ABSTRACT.
PUBLIC SECTION.
TYPES: BEGIN OF st_connection_details,
airport_from_id TYPE /dmo/airport_from_id,
airport_to_id   TYPE /dmo/airport_to_id,
departure_time  TYPE /dmo/flight_departure_time,
arrival_time    TYPE /dmo/flight_departure_time,
duration        TYPE i,
END OF st_connection_details.
DATA carrier_id    TYPE /dmo/carrier_id    READ-ONLY.
DATA connection_id TYPE /dmo/connection_id READ-ONLY.
DATA flight_date   TYPE /dmo/flight_date   READ-ONLY.
METHODS: get_connection_details
RETURNING
VALUE(r_result) TYPE st_connection_details.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
  1. 使用快速修复将以下私有组件从子类 LCL_PASSENGER_FLIGHT 移动("拉出")到超类 LCL_FLIGHT

  • 属性 计划类型

  • 属性 connection_details

  1. 在本地类 LCL_PASSENGER_FLIGHT 的定义部分中,将光标放在 planetype 上并选择 Ctrl + 1 以显示可用快速修复的列表。

  2. 从可用快速修复列表中,选择 Pull-Up planetype to superclass lcl_flight

  3. 对属性 connection_details 重复此操作。

  4. 超级类 LCL_FLIGHT 的定义部分现在应如下所示:

CLASS lcl_flight DEFINITION ABSTRACT.
PUBLIC SECTION.
TYPES: BEGIN OF st_connection_details,
airport_from_id TYPE /dmo/airport_from_id,
airport_to_id   TYPE /dmo/airport_to_id,
departure_time  TYPE /dmo/flight_departure_time,
arrival_time    TYPE /dmo/flight_departure_time,
duration        TYPE i,
END OF st_connection_details.
DATA carrier_id    TYPE /dmo/carrier_id    READ-ONLY.
DATA connection_id TYPE /dmo/connection_id READ-ONLY.
DATA flight_date   TYPE /dmo/flight_date   READ-ONLY.
METHODS: get_connection_details
RETURNING
VALUE(r_result) TYPE st_connection_details.
PROTECTED SECTION.
DATA planetype          TYPE /dmo/plane_type_id.
DATA connection_details TYPE st_connection_details.
PRIVATE SECTION.
ENDCLASS.
  1. 允许本地类 LCL_CARGO_FLIGHT 从本地类 LCL_FLIGHT 继承。

  2. 滚动到本地类 LCL_CARGO_FLIGHT 的定义部分。

  3. 如下调整代码:

CLASS lcl_cargo_flight DEFINITION
INHERITING FROM lcl_flight.
  1. 从本地类 LCL_CARGO_FLIGHT 中注释或移除冗余定义。

提示

使用问题视图中的语法错误导航到冗余定义。

  1. 问题 视图中,双击语法错误 。已存在名为"ST_CONNECTION_DETAILS"的类型

  2. 移除或注释本地类 LCL_CARGO_FLIGHT 中结构类型 ST_CONNECTION_DETAILS 的定义。

  3. 对已在超类 LCL_FLIGHT 中定义的其他组件重复此操作。

注意

不要忘记同时移除或注释方法 GET_CONNECTION_DETAILS 的实施。

  1. 通过在子类 LCL_CARGO_FLIGHT 中方法 CONSTRUCTOR 的实施开始时添加 super->constructor( ).,修复语法错误*"在构造函数方法中,只有在调用超类……的构造函数后才能访问实例属性..."*。

  2. 如下调整代码:

METHOD constructor.
super->constructor(  ).

任务 3: 重新定义方法

在父类中定义 GET_DESCRIPTION 方法并在子类中重新定义它。将实施的通用部分移动到父类,并保留子类中的特定部分。

步骤

  1. 在超类 LCL_FLIGHT 中,使用与子类中相同的参数定义公共实例方法 GET_DESCRIPTION

提示

从其中一个子类中复制方法定义。

  1. 如下调整代码:

CLASS lcl_flight DEFINITION ABSTRACT.
PUBLIC SECTION.
METHODS get_description
RETURNING
VALUE(r_result) TYPE string_table.
  1. 在局部类 LCL_PASSENGER_FLIGHTLCL_CARGO_FLIGHT 中,通过重新定义替换方法 GET_DESCRIPTION 的定义。

提示

使用问题视图中的语法错误导航到方法定义。

  1. 在两个子类的定义部分中,按如下所示调整代码:

*  METHODS get_description
*    RETURNING
*      VALUE(r_result) TYPE string_table.
METHODS get_description REDEFINITION.
  1. 使用快速修复将新 GET_DESCRIPTION 方法的空实施添加到本地类 LCL_FLIGHT

  2. 在本地类 LCL_FLIGHT 的定义中,将光标放在 get_description 上并按 Ctrl + 1 调用可用的快速修复。或者,您可以选择代码左侧带有灯泡的错误图标。

  3. 从建议清单中,选择添加实施 get_description

  4. 在局部类 LCL_PASSENGER_FLIGHT 中,调整方法 GET_DESCRIPTION 的实施。实施开始时,从超级类调用实施并将结果存储在参数 r_result 中。

  5. 添加以下代码:

r_result = super->get_description( ).
  1. 将处理以下继承属性值的代码从子类 LCL_PASSENGER_FLIGHT 移动到超类 LCL_FLIGHT 中方法 GET_DESCRIPTION 的实施:carrier_idconnection_idflight_dateconnection_details-airport_from_idconnection_s-airport_to_idplanetype

  2. 突出显示局部变量 txt 的声明和准备,以及 txt 变量和 planetype 属性的两个 APPEND 语句,然后按 Ctrl + C 将代码片段复制到剪贴板。

  3. Ctrl + < 在所选代码行的开头添加注释符号。

  4. 切换到本地类 LCL_FLIGHT 中方法 GET_DESCRIPTION 的实施,将光标放在语句 METHOD… 和 ENDMETHOD 之间,然后按 Ctrl + V 插入代码片段。

  5. 然后,超类中的实施应如下所示:

METHOD get_description.
DATA txt TYPE string.
txt = 'Flight &carrid& &connid& on &date& from &from& to &to&'(005).
txt = replace( val = txt sub = '&carrid&' with = carrier_id ).
txt = replace( val = txt sub = '&connid&' with = connection_id ).
txt = replace( val = txt sub = '&date&'   with = |{ flight_date DATE = USER }| ).
txt = replace( val = txt sub = '&from&'   with = connection_details-airport_from_id ).
txt = replace( val = txt sub = '&to&'     with = connection_details-airport_to_id ).
APPEND txt TO r_result.
APPEND |{ 'Planetype:'(006)      } { planetype }| TO r_result.
ENDMETHOD.
  1. 在局部类 LCL_CARGO_FLIGHT 中,相应地调整方法 GET_DESCRIPTION 的实施:调用方法 GET_DESCRIPTION 的继承实施并移除或注释冗余 APPEND 语句。

  2. 如下调整代码:

METHOD get_description.
r_result = super->get_description( ).
*    APPEND |Flight { carrier_id } { connection_id } on { flight_date DATE = USER } | &&
*           |from { connection_details-airport_from_id } to { connection_details-airport_to_id }|
*      TO r_result.
*    APPEND |Planetype:     { planetype }|
*      TO r_result.
APPEND |Maximum Load:  { maximum_load         } { load_unit }| TO r_result.
APPEND |Free Capacity: { get_free_capacity( ) } { load_unit }| TO r_result.
ENDMETHOD.

任务 4: 添加公用构造函数

在超类 LCL_FLIGHT 中,使用两个子类构造函数共有的输入参数定义实例构造函数。调整子类中超级类构造函数的调用,以便它们转发公用参数。然后将构造函数逻辑的通用部分从子类构造函数移动到超类构造函数。

步骤

  1. 在超类 LCL_FLIGHT 中,定义与子类 LCL_PASSENGER_FLIGHTCONSTRUCTOR 具有相同输入参数的 CONSTRU**C**TOR 方法。

提示

实例构造函数方法没有拉取快速修复。而是将方法定义从子类复制并粘贴到父类。

  1. 滚动到本地类 LCL_PASSENGER_FLIGHT 的定义部分。

  2. 为方法 CONSTRUCTOR 选择完整的 METHODS 语句,然后按 Ctrl + C 将代码片段复制到剪贴板。

  3. 向上滚动到本地类 LCL_FLIGHT 的定义部分,将光标放在 PUBLIC SECTION 语句之后,然后按 Ctrl + V 从剪贴板插入代码片段。

  4. 调整子类中超级类构造函数的调用。将导入参数转发到超类构造函数。

提示

使用问题视图中的语法错误导航到超类构造函数的调用。

  1. 在两个子类构造函数中,按如下所示调整代码:

METHOD constructor.
super->constructor(
i_carrier_id    = i_carrier_id
i_connection_id = i_connection_id
i_flight_date   = i_flight_date ).
  1. 使用快速修复为超类构造函数添加空实施。

  2. 在本地类 LCL_FLIGHT 的定义中,将光标放在 constructor 上并按 Ctrl + 1 调用可用的快速修复。

  3. 从建议列表中,选择添加构造函数实施

  4. 将继承属性 carrier_idconnection_idflight_date 的值分配从子类构造函数移动到超类构造函数。

  5. 导航到本地类 LCL_PASSENGER_FLIGHT 中方法 CONSTRUCTOR 的实施。

  6. 为继承属性 carrier_idconnection_idflight_date 选择值分配,然后按 Ctrl + C 将代码片段复制到剪贴板。

  7. Ctrl + < 在所选代码行的开头添加注释符号。

  8. 切换到本地类 LCL_FLIGHT 中方法 CONSTRUCTOR 的实施,在 METHOD… 和 ENDMETHOD 之间放置光标,然后按 Ctrl + V 插入代码片段。

  9. 然后,超类中的实施应如下所示:

METHOD constructor.
me->carrier_id    = i_carrier_id.
me->connection_id = i_connection_id.
me->flight_date   = i_flight_date.
ENDMETHOD.
  1. 切换到本地类 LCL_CARGO_FLIGHT 中方法 CONSTRUCTOR 的实施,然后移除或注释冗余值分配。

  2. 以控制台应用形式激活并测试全局类。调试本地类 LCL_PASSENGER_FLIGHT 的实例化以及方法 GET_DESCRIPTION 的调用。

  3. Ctrl + F3

  4. F9