One of the significant principles of inheritance is that an instance from a subclass can be used in every context in which an instance from the superclass appears. This is possible because the subclass has inherited all components from the superclass and therefore has the same interface as the superclass. The user can therefore address the subclass instance in the same way as the superclass instance.

Variables of the type “reference to superclass” can also refer to subclass instances at runtime.

The assignment of a subclass instance to a reference variable of the type “reference to superclass” is described as a narrowing cast, because you are switching from a view with more detail to a view with less detail.

The description “up-cast” is also used.

What is a narrowing cast used for? A user who is not interested in the finer points of cargo or passenger planes (but only, for example, in the tank gauge) does not need to know about them. This user only needs to work with (references to) the lcl_airplane class. However, in order to allow the user to work with cargo or passenger planes, you would normally need a narrowing cast.

After the narrowing cast you can use the airplane reference to access the components of the cargo plane instance that were inherited from lcl_airplane, obviously in some cases with the limitations entailed by their visibility. You can no longer access the cargo-plane-specific part of the instance (cargo in the above example) using the airplane reference.

A reference variable always has two types: static and dynamic:

The static type of a reference variable is determined by variable definition using TYPE REF TO. It cannot and does not change. It establishes which attributes and methods can be addressed

The dynamic type of a reference variable is the type of the instance currently being referred to, it is therefore determined by assignment and can change during the program run. It establishes what coding is to be executed for redefined methods.

In the example, the static type of the airplane variable is always ‘REF TO lcl_airplane’, but its dynamic type after the cast is ‘REF TO lcl_cargo_airplane’.

The reference ME can be used to determine the dynamic type in the Debugger.

The type of case described above is known as a widening cast because it changes the view to one with more details. The instance assigned (a cargo plane in the above example) must correspond to the object reference (cargo_airplane in the above example), that is, the instance must have the details implied by the reference.

This is also known as a “down cast”.

The widening cast in this case does not cause an error because the reference airplane actually points to an instance in the subclass lcl_cargo_airplane. The dynamic type is therefore ‘REF TO lcl_cargo_airplane’.

Here the widening cast produces the MOVE_CAST_ERROR runtime error that can be caught with “CATCH ... ENDCATCH”, because the airplane reference does not point to an instance in the subclass lcl_cargo_airplane, but to a “general airplane object”. Its dynamic type is therefore ‘REF TO lcl_airplane’ and does not correspond to the reference type cargo_airplane.

The widening cast logically represents the opposite of the narrowing cast. The widening cast cannot be checked statically, only at runtime. The Cast Operator “?=” (or the equivalent “MOVE ... ?TO …”) must be used to make this visible.

With this kind of cast, a check is carried out at runtime to ensure that the current content of the source variable corresponds to the type requirements of the target variables. In this case therefore, it checks that the dynamic type of the source reference airplane is compatible with the static type of the target reference cargo_airplane. If it is, the assignment is carried out. Otherwise the catchable runtime error “MOVE_CAST_ERROR” occurs, and the original value of the target variable remains the same.

A subclass instance can be used in any context in which a superclass instance also appears. Moreover: the user does not and is not intended to know whether he/she is dealing with a subclass or a superclass. The user therefore works only with references to the superclass and must rely on the inherited components behaving in the subclass instances exactly as they do in the superclass instances, otherwise the program will not work!

On the other hand, this ensures useful restrictions on the implementation of the subclasses: inherited components must keep their inherited semantics. You cannot use inherited attributes or events in any way other than intended in the superclass, and you cannot change method semantics by redefinition!

You must avoid coding inheritance: it is not correct for one class to inherit from another simply because part of the functionality required is already implemented there.


reviewCRM Middle ware Data Load and Monitoring
SAP Solution Manager Overview
People Centric SAP CRM Introduction
CRM Technical Infrastructure

1 comment :