OOABAP: Calling a class method with a class object - abap

In the program e1 is class event and c1 a class method. I tried calling class event using invocation for class methods c1=>t1 and invocation for object methods c1->t1 and both are successful. why?
As we know class methods are always called by c1=>t1.
REPORT my_event7.
CLASS c1 DEFINITION.
PUBLIC SECTION.
CLASS-EVENTS: e1.
METHODS: m1 FOR EVENT e1 OF c1.
CLASS-METHODS : t1.
ENDCLASS. "c1 DEFINITION
CLASS c1 IMPLEMENTATION.
METHOD : t1.
WRITE:/5 'C1->T1'.
RAISE EVENT e1.
ENDMETHOD.
METHOD : m1.
WRITE:/5 ' C1->M1'.
ENDMETHOD. ":
ENDCLASS. "c1 IMPLEMENTATION
CLASS c2 DEFINITION.
PUBLIC SECTION.
METHODS: m2 FOR EVENT e1 OF c1.
ENDCLASS. "c2 DEFINITION
CLASS c2 IMPLEMENTATION.
METHOD : m2.
WRITE:/5 ' C2->M2'.
ENDMETHOD.
ENDCLASS. "c2 IMPLEMENTATION
START-OF-SELECTION.
DATA: oref1 TYPE REF TO c1.
DATA: oref2 TYPE REF TO c2.
CREATE OBJECT: oref1 .
CREATE OBJECT: oref2 .
SET HANDLER oref1->m1 oref2->m2.
CALL METHOD c1=>t1.
CALL METHOD oref1->t1.

You may call it syntactical sugar.
Class methods can be called without any instance with <classname>=>method.
But you can also call the class method via the instance of the class. And then you can use the normal method call with ->. But in background the class method is called.

Related

Kotlin Inheritance for Multiple Constructor Supertype

I'm trying to inherit the JFrame class. It says "This type has a constructor, and thus must be initialized here" so I can't write:
class MainFrame : JFrame
but:
class MainFrame() : JFrame()
Since I'm forced to declare a primary constructor I can't do this:
constructor(title: String) : super(title)
And I have to do this:
constructor(title: String) : this(title)
So I have to declare the primary constructor this way:
class MainFrame(title: String) : JFrame(title)
The problem is that this way every secondary constructor needs to call the primary constructor and then the supertype constructor of choice. If I have multiple supertype constructors I'm forced to delegate the process to that single supertype constructor that can be inconvenient if the supertype class has many constructors for many purposes.
There is some way to make a class with multiple constructors that call different supertype constructors?
Edit:
I can't remove the supertype constructor like this:
class MainFrame : JFrame
If I do I get this error:
This type has a constructor, and thus must be initialized here
Solution:
A constructor was missing but it can be a secondary constructor, so the error:
This type has a constructor, and thus must be initialized here
Can be solved by adding only a secondary constructor.
It is not necessary to use a primary constructor in your class definition. You can simply omit it, and then all your "secondary" constructors do not have to call a primary constructor, and can call the relevant super constructor instead.
class MainFrame: JFrame {
constructor() : super() {
}
constructor(title: String) : super(title) {
}
}
JFrame, does however follow the pattern of having an unofficial primary constructor in Java, so you could call through to this as your primary constructor and use the same defaults it uses:
class MainFrame(title: String = "", gc: GraphicsConfiguration? = null): JFrame(title, gc) {
}

Can't hide val from supertype constructor

I have a class that extends a parent class like this:
abstract class BaseClass(val mem: Type)
class MyClass(val mem: Type) : BaseClass(mem)
I've declared the member as an argument of the constructor on MyClass because the BaseClass it extends from requires something be passed in, however this doesn't work because the compiler tells me that mem "hides member of supertype". I want this argument to be a member of the BaseClass, hence the use of val. How do I pass through the argument from MyClass?
While the argument in the constructor of BaseClass should be a val, the argument in the constructor of MyClass doesn't need to be. This is because it can just be an argument in the constructor that isn't part of the object. Since it is passed to BaseClass where it becomes a property of the object, and is, by definition, available in MyClass:
class MyClass(mem: Type) : BaseClass(mem)

Statement not accessible

there is error in line 49 where I wrote CALL METHOD lclref->lcm . how can i solve it?
REPORT ZPRACTICE_TILL_NOW.
include zlc.
include zinc.
START-OF-SELECTION.
create OBJECT lclref.
CALL METHOD lclref->lcm .
first include:
class zlcl DEFINITION.
PUBLIC SECTION.
METHODS: lcm.
ENDCLASS.
CLASS zlcl IMPLEMENTATION.
method lcm.
new-LINE.
WRITE: 'method called '.
ENDMETHOD.
ENDCLASS.
second include:
*&---------------------------------------------------------------------*
*& Include ZINC
*&---------------------------------------------------------------------*
data lclref TYPE REF TO zlcl.
The error 'Statement not accessible' is because lclref is an object .
To call a method of an object which is referenced to a class ( in this case object -> lclref and class ->zlcl ).
you can directly specify the object and the method .
Hence the corrected code would be : lclref->lcm.
Have fun.
*&---------------------------------------------------------------------*
*& Include ZINC
*&---------------------------------------------------------------------*
data lclref TYPE REF TO zlcl.
Are you sure first INCLUDE is zinc
class zlcl DEFINITION.
PUBLIC SECTION.
METHODS: lcm.
ENDCLASS.
CLASS zlcl IMPLEMENTATION.
method lcm.
new-LINE.
WRITE: 'method called '.
ENDMETHOD.
ENDCLASS.
When I tried with your code I did not getting any error. Please check your INCLUDE which one is the first?
I do not know your SAP version If supports you can use inline declaration. You can see the below example. No need to an extra data declarations
DATA(lo_lcl) = new zlcl( ).
lo_lcl->lcm( ).

Init method inheritance

If I have abstract class A with an init method:
abstract class A(){
init {
println("Hello")
}
}
And then class B that extends A
class B(): A()
If I instantiate B like this
fun main(args: Array<String>){
B()
}
Does the init method in A still get run and Hello gets printed?
And if not, what do I need to do to have the init method of A get run?
Yes, an init block of a base class gets run when the derived class instance is initialized.
In Kotlin, similarly to Java, an instance of a class is constructed in the following way:
An object is allocated.
The constructor of the class is called. (a)
If the class has a superclass, the superclass constructor is called before the class construction logic is executed; (i.e., the point (a) is executed recursively for the superclass, then the execution continues from here)
If the class has property initializers or init blocks, they are executed in the same order as they appear in the class body;
If the constructor has a body (i.e. it is a secondary constructor) then the body is executed.
In this description, you can see that, when B is constructed, the constructor of A is called before B initialization logic is executed, and, in particular, all init blocks of A are executed.
(runnable demo of this logic)
A small remark on terminology: init block is not actually a separate method. Instead, all init blocks together with member property initializers are compiled into the code of the constructor, so they should rather be considered a part of the constructor.

SCJP v6 (Sierra,Bates) Chapter 2, Question 12 Interpretations of constructor calls

Could I have some feedback on this
Given "new House("x ")" sends a string I had expected that the "House(String name)" constructor would have called the Building super class constructor "Building(String name)". In which case the answer would have been "bn x h hn x". However the answer is "b h hn x" (and yes it does run with that output).
Questions
1. Other than a call "new Building("string_value")" would there be a situation when House would call the "Building(String name)" constructor? (ie other than additional code in the House constructors?
2.Why is it that the no argument Building constructor is called, rather than the overloaded Building (String name) constructor? What I am looking is a possibility there could be many Building constructors and there could be a need to call specific super constructors from subclasses. How do you ensure which constructor (given two or more choices) is called?
Code included for ease of reference.
The answer is "b h hn x"
class Building {
Building() {System.out.print("b ");}
Building(String name) {this(); System.out.print("bn "+name);}
}
public class House extends Building {
House() {System.out.print("h ");}
House(String name) { this();System.out.print("hn "+name);}
public static void main(String a[]) {
new House("x "); }
}
Regards
Scott
If no explicit superclass constructor call is provided, and no call to a constructor in the same class is provided either, the no-args superclass constructor is always called. That's how Java is designed, and it would be too complicated and inefficient for the JVM to record which was the first constructor called and try and match it up with a superclass constructor.
If you needed to call a different superclass constructor, you would just call it explicitly, like this:
super(foo,bar);
When inheriting from another class, you must call super() in your constructor. If you don't, the compiler will insert that call for you as you can plainly see.
The superclass constructors are called because otherwise the object would be left in an uninitialized state.
Your program execution order is given below:
new House("x "); // call in main this will call same class default constructor because of this(), as you knew already that first statement must be either this() or super() if any
Call to this() in above constructor executes House() constructor. Now in House() there is no this() call so compiler puts default super() which will call base class default constructor and
hence the output is b h hn x