Context:
Classes ValueTypes Interfaces Type Members
method-id methodA static. 01 s string value "Hello". procedure division. display s end method.
method-id methodB (paramA AS binary-short paramB AS binary-short) RETURNING paramC AS binary-short. set paramC = paramA * paramB end method.
See also the Core sample, which is available from $COBDIR/demo.
Methods can be either static methods or instance methods, and are by default instance. An instance method operates on a given instance of a class, whereas a static method does not operate on a given instance.
A static method can access static methods and static fields in its own class. It can also access instance methods and fields, in its own class or any other class, by constructing an object of the required class and accessing the method or field via that object.
For example, the following class contains static and instance methods, and static and instance fields.
class-id MyCounter. 01 totalCount binary-long static. 01 myCount binary-long. method-id New. procedure division. set myCount to totalCount set totalCount to totalCount + 1 end method. method-id GetCount. procedure division returning returnItem as binary-long. set returnItem to myCount end method. method-id GetTotalCount static. procedure division returning returnItem as binary-long. set returnItem to totalCount end method. method-id SetCount static. procedure division using by value aCount as binary-long. set totalCount to aCount end method. end class.
Here is the program that invokes the above code:
program-id StaticInstanceProgram. 01 myInstance1 type MyCounter. 01 myInstance2 type MyCounter. procedure division. invoke type MyCounter::SetCount(10) set myInstance1 to new type MyCounter set myInstance2 to new type MyCounter display myInstance1::GetCount() *> displays 10 display myInstance2::GetCount() *> displays 11 display type MyCounter::GetTotalCount() *> displays 12 end program.
To use static and instance methods:
The following modifiers indicate the extent to which the method inherits and is inherited:
specifies that this method overrides the inherited method of the same name and signature.
hides the superclass method only when the redefine method is invoked on an item defined as being of the subclass type.
An abstract method has no implementation. To use an abstract method, you inherit it and in the inheriting subclass, you provide the implementation of the method. An abstract class can contain methods that are not abstract, as well as abstract ones. The methods that aren't abstract can provide a default implementation, which can be overridden by a subclass method. For example:
class-id MyAbstractClass abstract. 01 myField value 0 binary-long property. method-id AbstractMethod abstract. *> no implementation end method. method-id NonAbstractMethod. *> not abstract procedure division. set myField to 1 *> Default behavior, which can be overridden end method. end class.
Non-abstract methods in an abstract class can provide a default implementation, which can be overridden by a subclass method.
class-id MySubClass inherits type MyAbstractClass. method-id AbstractMethod override. procedure division. *> Subclass method implements abstract method display "myField is: " myField *> displays 0 end method. method-id NonAbstractMethod override. procedure division. *> Subclass method overrides method that is not abstract set myField to 6 display "myField is: " myField *> displays 6 end method. end class.
To define and use methods in abstract classes:
An override method is a method that overrides an inherited virtual method of the same name and signature.
For example, a subclass Circle inherits from a superclass Shape. Both classes contain a Draw method. The Draw method in the Circle subclass overrides the Draw method in the Shape superclass.
class-id Shape. method-id Draw. display "let's draw a super shape" end method. end class. class-id Circle inherits type Shape. method-id Draw override. display "let's draw a circle" end method. end class.
To define an override method:
You cannot override a final method in the inherited class. You can override only virtual methods (methods not defined as final).
The REDEFINE keyword is used to hide a method inherited from a class. To hide an inherited method, declare it in the derived class using the same name and specify REDEFINE.
A redefine method is similar to an override method, in that it is a method with the same name and signature as a method in the superclass. However, unlike an override method, the redefine method might or might not be executed depending on how it is invoked. When the method is invoked on an item defined as being in the:
For example, we have two subclasses Circle and Square, which inherit from the Shapes superclass. All the classes have a Draw method. The Circle class's Draw method overrides the Draw method in the Shapes superclass. The Square class's Draw method redefines the Draw method in the Shapes superclass.
class-id Shape. method-id Draw. display "let's draw a super shape" end method. end class. class-id Circle inherits type Shape. method-id Draw override. display "let's draw a circle" end method. end class.
class-id Square inherits type Shape. method-id Draw redefine. display "let's draw a square" end method. end class.
You can invoke the Circle and Square classes as follows:
program-id. RedefineSampleProgram. 01 myShape type Shape. 01 myCircle type Circle. 01 mySquare type Square. procedure division. set myShape to new type Shape set myCircle to new type Circle set mySquare to new type Square invoke myCircle::Draw *> Circle Draw method is invoked invoke mySquare::Draw *> Square Draw method is invoked *> Shape Draw method is hidden, redefined set myShape to myCircle *> Superclass instance is set to subclass invoke myShape::Draw *> Circle Draw method is invoked *> as it overrides Shape Draw method set myShape to mySquare *> Superclass instance is set to subclass invoke myShape::Draw *> Shape Draw method is invoked as *> Square Draw method doesn't override it end program.
The above invocations produce the following output:
let’s draw a circle let’s draw a square let’s draw a circle let’s draw a super shape
Another place to use REDEFINE is where the method in the superclass is defined as FINAL and so it cannot be overridden. In this case, you can use REDEFINE to hide the superclass method.
A method that is declared as final is prevented from being overridden in any subclasses. This enables a class to inherit a superclass, while preventing a specific superclass method from being overridden in the subclass.
For example, we have a class MySubClass, which inherits from MySuperClass. MySuperClass has one final method and one virtual (not final) method. The subclass overrides the virtual method, but it cannot inherit or override the final method.
class-id MySuperClass. method-id VirtualMethod. *> Methods are virtual by default procedure division. display "Virtual method in the superclass" end method. method-id FinalMethod final. *> Final methods are not virtual procedure division. display "Final method in the superclass" end method. end class.
The subclass is defined as follows:
class-id MySubClass inherits type MySuperClass. method-id VirtualMethod override. procedure division. display "Overridden virtual method in the subclass" end method. * method-id FinalMethod override. *>COBCH0954 Method 'FinalMethod' cannot OVERRIDE a nonvirtual method end class.
The classes are invoked as follows:
program-id FinalOverrideSampleProgram. 01 mySuper type MySuperClass. 01 mySub type MySubClass. procedure division. set mySuper to new type MySuperClass invoke mySuper::FinalMethod() invoke mySuper::VirtualMethod() set mySub to new type MySubClass invoke mySub::VirtualMethod() end program.
The above sample program produces output as follows:
Final method in the superclass Virtual method in the superclass Overridden virtual method in the subclass
Although a final method cannot be overridden in a subclass, it can be redefined in the subclass.
The EXTENSION keyword declares a method as an extension method.
Extension methods enable you to add methods to existing types without the need to edit or recompile the code. Extension methods appear as additional methods available on an object instance while they are implemented elsewhere.
For example, the following extension method extends the string class, by adding a method to count the number of words in a string:class-id MyCount static. method-id CountWords extension. *> extension method is implicitly static procedure division using by value str as string returning wordCount as binary-long. set wordCount to str::Split(' ')::Length end method. end class.
To declare an extension method:
There is no special syntax for calling extension methods from managed COBOL. You consume an extension method in the same way as any other method, except you specify the first parameter as if it were the instance on which the method is called:
parameter-1::method-name(more parameters)
In JVM COBOL, there are two extensions that are preloaded before compilation:
These two extensions ensure that managed COBOL produces the same results, regardless of whether it is compiled to JVM COBOL or .NET COBOL. For more detail, see Extension Methods and Operators.
The SYNC modifier locks the values of the arguments sent to the method, so that they do not change while the method is processing.
When an argument is sent to a method and is received as a reference parameter, the value of the parameter and its corresponding sending argument might be updated. Without the SYNC modifier, the value of the sending argument is unknown, while the method is processing.
The SYNC modifier on a method is equivalent to wrapping the whole method in a SYNC statement.
For example:
01 a binary-long value 20. ... invoke Adjust(a) display a *> displays 93 method-id Adjust sync (reference x as binary-long). set x to x + 73 end method. end class.
In the above example, the SYNC modifier is applied to the method Adjust(). This ensures that the variables within the method (in this case, the variable x locally, but variable a in the invoking code) cannot be accessed until the method has finished processing.
If the FOR clause is specified, this method is an Explicit Interface Member Implementation. The method may not be invoked explicitly. It will be invoked implicitly when the corresponding method is invoked on an instance of this class which has been cast to the interface type.
Use of explicit interface implementation (via the FOR clause) is particularly useful when the class implements two different interfaces, and these two interfaces have a method with the same name and signature. In this case, by using the FOR phrase, you can supply two different implementations of the method for the two different interfaces.interface-id. "IAlarm1". method-id checkAlarm. procedure division using atime as binary-long. end method. end interface. interface-id. "IAlarm2". method-id checkAlarm. procedure division using atime as binary-long. end method. end interface. class-id BasicAlarm implements type IAlarm1 type IAlarm2. method-id checkAlarm for type IAlarm1. procedure division using atime as binary-long. ... end method. method-id checkAlarm for type IAlarm2. procedure division using atime as binary-long. ... end method. end class.