Previous Topic Next topic Print topic


Methods

A method defines a block of code to be executed when the method is invoked.

method-specification

method-header constraints-paragraph procedure-division

method-header

access-modifier attribute-clause

Example

method-id methodA static.
01 s string value "Hello".
procedure division.
   display s
end method.

See also the Core sample, which is available from Start > All Programs > Micro Focus Studio Enterprise Edition x.x > Samples, under COBOL for .NET .

Static and Instance Methods

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 invoke static methods only and can access static fields only. A static method can reside in a static class or an instance class. Where a static method is in an instance class, all objects instantiated from the class share a single copy of the static methods.

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:

  • To declare a static method, use the STATIC keyword. If the method is in a static class, you must specify STATIC.
  • To declare an instance method, don't use the keyword STATIC.
  • To access a static method, you use the name of the class, followed by :: and then the method name. For example: MyCounter::GetTotalCount() as in the above code.
  • To access an instance method, you use the name of the instance object, then :: followed by the method. For example: myInstance1::GetCount() as in the above code.

Instance Method Modifiers

The following modifiers indicate the extent to which the method inherits and is inherited:

ABSTRACT
declares an empty method. To use an abstract method, you must inherit it and include the required code in the subclass.
OVERRIDE

specifies that this method overrides the inherited method of the same name and signature.

REDEFINE

hides a method in a superclass, where the subclass contains the redefine method. The REDEFINE keyword hides the superclass method only when the redefine method is invoked on an item defined as being in the subclass containing the redefine method.

FINAL
prevents a derived class from further overriding the method.

In summary, you can think of the keywords like this:

  • An abstract method provides the name and signature of a method
  • A virtual method is the first implementation of a method
  • An override method is another implementation of a method
  • A final method is the last implementation of a method

Abstract Methods

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.

An abstract class can contain methods that are not abstract. These methods 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: " self::myField  *> displays 0
       end method.
       
       method-id NonAbstractMethod override.
       procedure division.
           *> Subclass method overrides method that is not abstract
           set self::myField to 6  
           display "myField is: " self::myField  *> displays 6
       end method.
       
       end class.

To define and use methods in abstract classes:

  • You use the ABSTRACT keyword to define any members that are abstract, and omit it for members that are not abstract. Abstract members must be within an abstract class.
  • The subclass must inherit the abstract superclass, and must contain an implementation of all the abstract members of the superclass. However, the subclass itself can be abstract and in this case, will not contain implementations.
  • The subclass methods must use the keyword OVERRIDE.
  • An abstract method cannot be private. It can be public, protected or internal.

Override Methods

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:

  • Specify the OVERRIDE modifier in the method-id header
  • Ensure that the method has the same name and signature as the method to be overridden in the inherited class

You cannot override a final method in the inherited class. You can override only virtual methods (methods not defined as final).

Redefine Methods

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 override depending on how it is invoked. When the method is invoked on an item defined as being in the:

  • Superclass, even when that item actually holds an instance of the subclass, the superclass method is executed
  • Subclass - the subclass redefine method is executed and the superclass method is overridden

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 inherited nor overridden. In this case, you can use REDEFINE to hide the subclass method and use the superclass method instead, when polymorphism in use.

Final Methods

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 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.

Extension Methods

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 str as string 
                          returning wordCount as binary-long.
            set wordCount to str::Split(' ')::Length
       end method.
       end class.

To declare an extension method:

  • Use the EXTENSION keyword in the method header.
  • The method must be in a static class that is not nested or generic. The method is implicitly static.
  • In the method body, the first parameter is the type to extend. It is always a value parameter.

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 the type of the method, using this syntax:

parameter-1::method-name(more parameters)

In JVM COBOL, there are two extensions that are preloaded before compilation:

  • An extension operator for string equality
  • An extension method for substring

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.

Synchronized Methods

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 self::Adjust(a)
       display a                 *> displays 93
   
       method-id Adjust sync.
       procedure division using 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.

Invoking a Method

You can invoke a method in two ways: by using the INVOKE statement or by invoking inline using the SET statement.

Previous Topic Next topic Print topic