Recently I have discovered very interesting feature in Java. Below I will try to compare this with what ABAP can do about it.
Quick jump in
Overriding a method in ABAP and Java is simple. In the former we use REDEFINITION keyword in a subclass, in the latter we rewrite method with the same signature and provide our new implementation.
There is however one special feature which Java stays ahead compared to ABAP. Consider below class.
ABAP
CLASS lcl_super DEFINITION. PUBLIC SECTION. DATA: field TYPE c VALUE 'A'. METHODS: get_field RETURNING value(rv_field) TYPE char1. ENDCLASS. CLASS lcl_super IMPLEMENTATION. METHOD get_field. rv_field = field. ENDMETHOD. ENDCLASS.Java counterpart would be:
public class Superclass { public char field = 'A'; public char getField(){ return field; } }
Now we want a subclass inheriting from the superclass and providing its own get_field/getField method implementation.
CLASS lcl_sub DEFINITION INHERITING FROM lcl_super. PUBLIC SECTION. METHODS: get_field REDEFINITION. * I leave original implementation the same in redefined method on purpose ENDCLASS. CLASS lcl_sub IMPLEMENTATION. METHOD get_field. rv_field = field. ENDMETHOD. ENDCLASS.Java
public class Subclass extends Superclass { public char getField(){ return field; } }
So far, so good. If we write a client application using our both methods…
ABAP
DATA r_super TYPE REF TO lcl_super. DATA r_sub TYPE REF TO lcl_sub. CREATE OBJECT r_super. CREATE OBJECT r_sub. DATA char TYPE c. char = r_super->get_field( ). WRITE: / 'Superclass:', char. char = r_sub->get_field( ). WRITE: / 'Subclass:', char.Java
Superclass sup = new Superclass(); Subclass sub = new Subclass( ); System.out.println("Superclass:" + sup.getField()); System.out.println("Subclass:" + sub.getField());
…, the output is:
Superclass:A
Subclass:A
“Overriding” an attribute
Now we would want to add another component called FIELD in the subclass, hiding or “overriding” the original one inherited from the superclass.
ABAP
CLASS lcl_sub DEFINITION INHERITING FROM lcl_super. PUBLIC SECTION. DATA field TYPE c VALUE 'B'. METHODS: get_field REDEFINITION. ENDCLASS.Java
public class Subclass extends Superclass { public char field = 'B'; public char getField(){ return field; } }
ABAP here shouts on syntax check: “FIELD has already been declared” while Java stays calm. Now running Java client once again result is:
Superclass:A
Subclass:B
Nice? As you can see Java allows something that complains about. This is kind of “overriding” an attribute. Let’s have a look deeper in the rabbit hole.
Changing visibility
I change the visibility of an attribute in Subclass
private char field = 'B';
As the Subclass attribute covers Superclass’s we can manipulate it’s visibility independently of the former. The same is possible in reverse order. We can change it from private to public. This is because our FIELD attribute referenced by
sup.getField();
has nothing to do with below anymore
sub.getField();
We simply access two different components. One is of Supreclass, another is of Subclass. Decisive here is the object referenced by sup or sub variable.
Trapdoors
Couple of undesired behaviors:
- in Java when accessing the attribute directly static reference type matters
System.out.println("Superclass:" + sup.field);
sup = sub;
System.out.println("Subclass:" + sup.field);
The attribute which is accessed is the one of superclass
in both cases
Superclass:A
Subclass:A
System.out.println("Superclass:" + sup.getField());
sup = sub;
System.out.println("Subclass:" + sup.getField());
Result is:
Superclass:A
Subclass:B
Note!
Actually in whole Java language casting to more general type is possible i.e. you can return type int to long variable.
Be careful no to fall into one of the trapdoors!
Hello Marcin,
Thanks for the post. Nice to know about this feature of Java. I totally agree with – use with caution!
Regards,
Naimesh Patel
Hi Naimesh,
I actually forgot to mention. Hiding option also applies to STATIC methods in Java. But this should not confuse developer to much as addressing it is preety straightforward i.e.
Superclass.getStaticField(); //addresses Superclass’s static method
Subclass.getStaticField(); //addresses Subclass’s static method
Regards
Marcin
Nice to know that! Thanks.