In any Object Oriented programming language, the access to private or protected components – both methods and attributes – would be prohibited. If someone try to access them, compiler would generate syntax error.
Sometimes, it would be advantageous to give the access to these protected and private attributes to other classes. This can be achieved using the FRIENDS addition.
Design Consideration
This addition has to be added on class whose attribute needs to be accessed. We would refer this class as LCL_ME. Friend class who wants to access the other class’s attributes doesn’t need any special declaration. We would refer this class as LCL_FRIEND.
Simple Demo
CLASS lcl_me DEFINITION FRIENDS lcl_friend. PRIVATE SECTION. DATA: a1 TYPE string VALUE 'I am A1 of LCL_ME'. ENDCLASS. "lcl_me DEFINITION
Simple Demo
Lets see the simple Demo of using Friends class.
Friends declaration
REPORT zdemo_simple_friend. * CLASS lcl_friend DEFINITION. PUBLIC SECTION. METHODS: access_a1_of_class1. ENDCLASS. "lcl_friend DEFINITION * CLASS lcl_me DEFINITION FRIENDS lcl_friend. PRIVATE SECTION. DATA: a1 TYPE string VALUE 'I am A1 of LCL_ME'. ENDCLASS. "lcl_me DEFINITION * CLASS lcl_friend IMPLEMENTATION. METHOD access_a1_of_class1. DATA: lo_class1 TYPE REF TO lcl_me. CREATE OBJECT lo_class1. WRITE: / lo_class1->a1. ENDMETHOD. "access_a1_of_class1 ENDCLASS. "lcl_friend IMPLEMENTATION * START-OF-SELECTION. DATA: lo_friend TYPE REF TO lcl_friend. CREATE OBJECT lo_friend. lo_friend->access_a1_of_class1( ).
This demo shows us, that LCL_FRIEND has unlimited access to LCL_ME.
Subclasses of Friend
All the subclasses (LCL_FRIEND_KIDS) would be by default friends of the LCL_ME and would have unlimited access to all the components. Friend Class or its subclasses wont get access of Subclasses of accessed class (LCL_MY_KIDS), unless LCL_MY_KIDS are made friends to LCL_FRIEND.
Friend's Kids Accessing LCL_ME
REPORT znp_demo_friend_kids. * CLASS lcl_friend DEFINITION. PUBLIC SECTION. METHODS: access_a1_of_class1. ENDCLASS. "lcl_friend DEFINITION * CLASS lcl_friend_kids DEFINITION INHERITING FROM lcl_friend. PUBLIC SECTION. METHODS: my_access_a1. ENDCLASS. "lcl_friend_kids DEFINITION * CLASS lcl_me DEFINITION FRIENDS lcl_friend. PRIVATE SECTION. DATA: a1 TYPE string VALUE 'I am A1 of LCL_ME'. ENDCLASS. "lcl_me DEFINITION * CLASS lcl_friend IMPLEMENTATION. METHOD access_a1_of_class1. DATA: lo_class1 TYPE REF TO lcl_me. CREATE OBJECT lo_class1. WRITE: / lo_class1->a1. ENDMETHOD. "access_a1_of_class1 ENDCLASS. "lcl_friend IMPLEMENTATION * CLASS lcl_friend_kids IMPLEMENTATION. METHOD my_access_a1. DATA: lo_class1 TYPE REF TO lcl_me. CREATE OBJECT lo_class1. WRITE: / 'Accessing A1 from LCL_FRIEND_KIDS'. WRITE: / lo_class1->a1. ENDMETHOD. "my_access_a1 ENDCLASS. "lcl_friend_kids IMPLEMENTATION * START-OF-SELECTION. " Friend kid DATA: lo_friend_kids TYPE REF TO lcl_friend_kids. CREATE OBJECT lo_friend_kids. lo_friend_kids->my_access_a1( ).
Concrete Classes of a Friend Interface
We can also specify an interface as the friends of the accessed class. If we do so, all the classes who implements the interface LIF_FRIEND, would be automatically granted full access.
Friendship via Interface
REPORT znp_demo_friend_intf. * INTERFACE lif_friend. METHODS: access_a1_of_class1. ENDINTERFACE. "lif_friend * CLASS lcl_friend DEFINITION. PUBLIC SECTION. INTERFACES: lif_friend. ENDCLASS. "lcl_friend DEFINITION * CLASS lcl_friend_2 DEFINITION. PUBLIC SECTION. INTERFACES: lif_friend. ENDCLASS. "lcl_friend_2 DEFINITION * CLASS lcl_me DEFINITION FRIENDS lif_friend. PRIVATE SECTION. DATA: a1 TYPE string VALUE 'I am A1 of LCL_ME'. ENDCLASS. "lcl_me DEFINITION * CLASS lcl_friend IMPLEMENTATION. METHOD lif_friend~access_a1_of_class1. DATA: lo_class1 TYPE REF TO lcl_me. CREATE OBJECT lo_class1. WRITE: / 'Accessing A1 from LCL_FRIEND via LIF_FRIEND'. WRITE: / lo_class1->a1. ENDMETHOD. "access_a1_of_class1 ENDCLASS. "lcl_friend IMPLEMENTATION * CLASS lcl_friend_2 IMPLEMENTATION. METHOD lif_friend~access_a1_of_class1. DATA: lo_class1 TYPE REF TO lcl_me. CREATE OBJECT lo_class1. WRITE: / 'Accessing A1 from LCL_FRIEND_2 via LIF_FRIEND'. WRITE: / lo_class1->a1. ENDMETHOD. "my_access_a1 ENDCLASS. "lcl_friend_2 IMPLEMENTATION * START-OF-SELECTION. " Friend Access via Interface DATA: lo_friend TYPE REF TO lif_friend. CREATE OBJECT lo_friend TYPE lcl_friend. lo_friend->access_a1_of_class1( ). " another friend CREATE OBJECT lo_friend TYPE lcl_friend_2. lo_friend->access_a1_of_class1( ).
Subclasses of LCL_ME are not friends
Inherited classes of LCL_ME are not direct friends of LCL_FRIEND which is friends of LCL_ME. In other words, friendship is not directly inherited, it has to be defined by the class definition.
Conclusion
As we can see, friendship has lot of power. Friend class would have unlimited access to all the components. From a design perspective, it would be slight risky to make a friend as inheritance of friend would also have unlimited access.
Concept of Friends are being discussed at: Friend Classes
superb naimesh!
made it simple .. thank you Naimesh !!