COBOL / C# /Java Comparison

advertisement
COBOL / C# /Java Comparison
COBOL
C#
Java
Program Structure
class-id HelloWorld as "Hello.Helloworld".
method-id main static.
local-storage section.
01 helloString string value "COBOL".
procedure division using by value args as
string occurs any.
namespace Hello
{
public class HelloWorld
{
public static void Main(string[]
args)
{
string helloString = "C#";
if length of args > 0
set helloString to args(1)
end-if
display "Hello, " & helloString & "!"
end method.
if (args.Length > 1)
{
helloString = args[0];
}
System.Console.WriteLine("Hello, " +
helloString + "!");
}
}
}
end class.
package Hello;
public class HelloWorld
{
public static void main(String[]
args)
{
String helloString = "Java";
if (args.length > 1)
{
helloString = args[0];
}
System.out.println("Hello, "
+ helloString + "!");
}
}
Comments
* in column 7 when comments out rest of line
(COBOL fixed format)
*> rest of the line comment, may follow COBOL
statements
*>> <summary>XML comments</summary>
// Rest of line
/* Multiple
lines */
/// <summary>XML comments on single
line</summary>
/** <summary>XML comments on multiple
lines</summary> */
// Rest of the line
/* Multiple
line */
/** Java doc. Type /** Eclipse will
autocomplete */
Value Types
condition-value
binary-char unsigned, binary-char
character
binary-short (unsigned)
binary-long (unsigned)
binary-double (unsigned)
float-short, float-long
decimal
DateTime (not a built-in COBOL type)
Value Types
bool
byte, sbyte
char
short, ushort
int, uint
long, ulong
float, double
decimal
DateTime
(not a built-in C# type)
Value Types
boolean
byte
char
short
int
long
float, double
Reference types
object
string
Reference Types
object
string
Reference Types
java.lang.Object
java.lang.String
Initializing
01 isTrue condition-value
value true.
01 hex
binary-char unsigned value h"2a".
*> Hex
01 octal
binary-char unsigned value o"52".
*> Octal
01 person object
value null.
01 aName
string
value
"Dwight".
01 grade
character
value "B".
01 today
type DateTime
value
type
DateTime::Parse("12/31/2007 12:15:00").
01 amount decimal
value 35.99.
01 gpa
float-short
value 2.9.
01 pi
float-long
value
3.14159265.
01 lTotal binary-double
value
123456.
01 sTotal binary-short
value 123.
01 usTotal binary-short unsigned value 123.
01 uiTotal binary-long
value 123.
01 ulTotal binary-long unsigned value 123.
Initializing
bool
isTrue
byte
hex
Data Types
Type Information
01 x binary-long.
display x::GetType
System.Int32
display type of binary-long
System.Int32
display x::GetType::Name
Type Conversion
01 d float-short value 3.5.
conversion
set i to d as binary-long
(truncates decimal)
*> Prints
= true;
= 0x2A;
// hex
object
person = null;
string
aName
= "Dwight";
char
grade
= 'B';
DateTime today
=
DateTime.Parse("12/31/2007 12:15:00");
decimal
float
double
long
short
ushort
uint
ulong
amount
gpa
pi
lTotal
sTotal
usTotal
uiTotal
ulTotal
=
=
=
=
=
=
=
=
35.99m;
2.9f;
3.14159265;
123456L;
123;
123;
123;
123;
Type Information
int x;
Console.WriteLine(x.GetType());
// Prints System.Int32
Console.WriteLine(typeof(int));
// Prints System.Int32
Console.WriteLine(x.GetType().Name);
// prints Int32
Type Conversion
float d = 3.5f;
*> Prints Int32 int i = (int)d;
// set to 3
(truncates decimal)
*> Prints
*> automatic
*> set to 3
COBOL types not supported in C# or Java
*> Only a few examples here
01 displayNumber pic 9(9).99.
01 computeNumber pic 9(9)V99.
01 alphaNumberic pic a(23).
01 binaryStorage pic x(12).
*> Also groups and redefines - a few examples
01 arecord.
03 aSubRecord pic x(10).
Date
(not a built-in Java)
Initializing
boolean correct = true;
byte
b
= 0x2A;
// hex
Object person = null;
String name
= "Dwight";
char
grade
= 'B';
Date
today
=
Date.parse("12/31/2007 12:15:00");
float
double
long
short
int
gpa
pi
lTotal
sTotal
iTotal
=
=
=
=
=
2.9f;
3.14159265;
123456L;
123;
123;
Type Information
Use reflection
Type Conversion
float d = 3.5f;
int i = (int)d;
// set to 3
(truncates decimal)
03 aUnion
aSubrecord.
pic 9(10) redefines
Constants
78 MAX_STUDENTS value 25.
public, binary-long...
*> optionally
*> INITIALIZE ONLY - instance or static, may
be initialized in constructor
01 MIN_DIAMETER float-short value 4.93
initialize only.
const int MAX_STUDENTS = 25;
final int MAX_STUDENTS = 25;
// Can set to a const or var; may be
initialised in a constructor
readonly float MIN_DIAMETER = 4.93f;
Enumeration
enum-id Action.
enum Action {Start, Stop, Rewind,
78 #Start.
*> Start is a reserved word
Forward};
78 #Stop.
enum Status {Flunk = 50, Pass = 70,
78 #Rewind.
Excel = 90};
78 #Forward.
end enum.
Action a = Action.Stop;
enum-id Status.
if (a != Action.Start)
78 Flunk value 50.
Console.WriteLine(a + " is " + (int)
78 Pass value 70.
a);
// Prints "Stop is 1"
78 Excel value 90.
end enum.
Console.WriteLine((int) Status.Pass);
program-id main.
// Prints 70
display type Status::Pass as binary-long *> Console.WriteLine(Status.Pass);
prints 70
// Prints Pass
display type Status::Pass
*>
prints Pass
end program.
enum Action {Start, Stop, Rewind,
Forward};
public enum Status
{
Flunk (50), Pass (70), Excel
(90);
private final int val;
Status(int valIn)
{
this.val = valIn;
}
}
Action a = Action.Stop;
if (a != Action.Start)
System.out.println(a);
// Prints "Stop"
System.out.println(Status.Pass.val);
// Prints 70
System.out.println(Status.Pass);
Operators
Comparison
= < > <= >= <>
Comparison
== < > <=
Arithmetic
+ - * /
function mod
*>no direct COBOL equivalent to integer
division
**
Arithmetic
+ - * /
% (mod)
/ (integer division if both operands
are ints)
Math.Pow(x, y)
Arithmetic
+ - * /
% (mod)
/ (integer division if both operands
are ints)
Assignment
move, set, compute
Assignment
= += -= *=
>>= ++ --
Assignment
= += -= *= /=
<<= >>= ++ --
Bitwise
b-and, b-or, b-xor, b-not, b-left, b-right
Logical
and, or, not
String Concatenation
&
Bitwise
&
|
^
Logical
&&
||
>=
/=
~
&
Comparison
== < > <=
!=
%=
<<
|
&=
|=
^=
<<=
>>
^
!
Bitwise
&
|
^
>=
Logical
&&
||
~
!=
&
%=
<<
|
&=
|=
^=
>>
^
!
//Note: && and || perform short-circuit
logical evaluations
String Concatenation
+
String Concatenation
+
Choices
*>COBOL has no exact equivalent syntax to x ? greeting = age < 20 ? "What's up?" :
y : z
"Hello";
greeting = age < 20 ? "What's up?" :
"Hello";
if age < 20
move "What's up?" to greeting
else
move "Hello" to greeting
end-if
// Good practice is that all
consequents are enclosed in {}
// although optional if 1 line
if (age < 20)
greeting = "What's up?";
else
greeting = "Hello";
if x not = 100 and y < 5
multiply 5 by x
multiply 2 by y
end-if
// Good practice is that all consequents
are enclosed in {}
// or are on the same line as if.
if (age < 20) greeting = "What's up?";
else
{
greeting = "Hello";
}
// Multiple statements must be enclosed
in {}
if (x != 100 && y < 5)
{
*> evaluate is preferred in COBOL rather than
x *= 5;
if/else if/else
y *= 2;
evaluate x
}
when > 5
multiply y by x
when 5
if (x > 5)
add y to x
{
when < 10
x *= y;
subtract y from x
}
when other
else if (x == 5)
divide y into x
{
end-evaluate
x += y;
}
else if (x < 10)
evaluate color
*> can be any type
{
when "turquoise"
x -= y;
when "red"
}
add 1 to r
else
when "turquoise"
{
add 1 to b
x /= y;
when "green"
}
// Multiple statements must be
enclosed in {}
if (x != 100 && y < 5)
{
x *= 5;
y *= 2;
}
if (x >
{
x *=
}
else if
{
x +=
}
else if
{
x -=
}
else
{
x /=
}
5)
y;
(x == 5)
y;
(x < 10)
y;
y;
// prints Pass
add 1 to g
when other
add 1 to other-color
end-evaluate
// Every case must end with break or
goto case
switch (color)
//
Must be integer or string
{
case "turquoise":
case "red":
r++;
break;
case "turquoise":
b++;
break;
case "green": g++;
break;
default:
other++;
break;
//
break necessary on default
}
switch (color)
{
case "turquoise":
case "red":
r++;
break;
case "turquoise":
b++;
break;
case "green":
g++;
break;
default:
other++;
break;
}
Loops
Pre-test loops:
perform until c >= 10
add 1 to c
end-perform
perform varying c from 2 by 2 until c > 10
display c
end-perform
Post-test loops:
perform with test after until c >= 10
add 1 to c
end-perform
Array or collection looping
01 names string occurs any.
01 s string.
set content of names to ("Rod", "Jane",
"Freddy")
perform varying s through names
display s
end-perform
Breaking out of loops:
01 i binary-long value 0.
perform until exit
if i = 5
exit perform
end-if
add 1 to i
end-perform
Continue to next iteration:
01 i binary-long value 0
perform varying i from 0 by 1 until i >= 5
if i < 4
exit perform cycle
end-if
display i
*> Only prints 4
end-perform
Pre-test Loops:
// no "until" keyword
while (c < 10)
{
c++;
}
for (c = 2; c <= 10; c += 2)
{
Console.WriteLine(c);
}
Pre-test Loops:
while (c < 10)
{
c++;
}
for (c = 2; c <= 10; c += 2)
{
System.out.println(c);
}
Post-test Loop:
do
{
c++;
} while (c < 10);
Post-test Loop:
do
{
c++;
} while (c < 10);
Array or collection looping
string[] names = {"Rod", "Jane",
"Freddy"};
foreach (string s in names)
{
Console.WriteLine(s);
}
Array or collection looping
String[] names = {"Rod", "Jane",
"Freddy"};
for (int i = 0; i < names.length;
i++)
{
System.out.println(names[i]);
}
Breaking out of loops
int i = 0;
while (true)
{
if (i == 5)
{
break;
}
i++;
}
Breaking out of loops
int i = 0;
while (true)
{
if (i == 5)
{
break;
}
i++;
}
Continue to next iteration
Continue to next iteration
for (i = 0; i < 5; i++)
{
for (i = 0; i < 5; i++)
if (i < 4)
{
{
if (i < 4)
continue;
{
}
continue;
Console.WriteLine(i);
// Only prints
}
4
System.out.println(i);
// Only
}
prints 4
}
Arrays
01 nums binary-long occurs 3 values 1, 2, 3.
*> Can also do:
set content of nums to (1, 2, 3)
*>
01
*>
01
5 is the size of the array
names string occurs 5.
Can also do:
names string occurs any.
set size of names to 5
set names(1) to "Rod" *> first element
indexed as 1
set names(6) to "Jane" *> throws
IndexOutOfRangeException
*> COBOL cannot resize an array - use copy
01 names2 string occurs 7.
invoke type Array::Copy(names, names2,
names::Length)
*> or else:
invoke names::CopyTo(names2, 0)
*> or else:
invoke type Array::Resize(names, 7)
int[] nums = {1, 2, 3};
for (int i = 0; i < nums.Length; i++)
{
Console.WriteLine(nums[i]);
}
int[] nums = {1, 2, 3};
for (int i = 0; i < nums.length; i++)
{
System.out.println(nums[i]);
}
// 5 is the size of the array
string[] names = new string[5];
names[0] = "Rod";
names[5] = "Jane";
// Throws
System.IndexOutOfRangeException
// 5 is the size of the array
String[] names = new String[5];
names[0] = "Rod";
names[5] = "Jane"; // Throws
java.lang.ArrayIndexOutOfBoundsExcept
ion
// C# can't dynamically resize an array.
Just copy into new array.
// Copy an array into a new array.
string[] names2 = new string[7];
String[] names2 = new String[7];
// or names.CopyTo(names2, 0);
Array.Copy(names, names2, names.Length); System.arraycopy(names, 0, names2, 0,
names.length);
float[,] twoD = new float[rows, cols];
twoD[2,0] = 4.5f;
float[][] twoD;
twoD = new float[rows][cols];
01 twoD float-short occurs any, any.
set size of twoD to rows, cols
int[][] jagged = new int[3][] {
new int[5], new int[2], new int[3] };
01 jagged binary-long occurs any, occurs any. jagged[0][4] = 5;
set size of jagged to 3
set size of jagged(1) to 5
set jagged(1, 5) to 5
// In Java this is just a multidimensional array
int[][] jagged = {{1, 2, 3},
{1, 2, 3, 4,
5},
{1, 2}};
System.out.println("jagged[0][2] = "
+ jagged[0][2]); //prints 3
Functions
method-id TestFunc.
procedure division using value x as binarylong,
reference y as
binary-long,
output z as binarylong.
add 1 to x, y
move 5 to z
end method.
// Pass by value (in, default),
reference (in/out),
// and reference (out)
void TestFunc(int x, ref int y, out int
z)
{
x++;
y++;
z = 5;
}
01 a binary-long value 1.
01 b binary-long value 1.
01 c binary-long. *> c doesn't need
initializing
int a = 1, b = 1, c; // c doesn't need
initializing
TestFunc(a, ref b, out c);
Console.WriteLine("{0} {1} {2}", a, b,
c); // 1 2 5
invoke self::TestFunc(value a, reference b,
output c)
*> Or
invoke self::TestFunc(a, b, c)
display a space b space c
// Accept variable number of arguments
int Sum(params int[] nums)
{
int sum = 0;
foreach (int i in nums)
{
sum += i;
}
return sum;
}
*> sum is an intrinsic function in COBOL
01 total binary-long.
set total to function sum(4, 3, 2, 1) *>
returns 10
*> To create a non intrinsic variable
argument list function:
method-id MySum.
local-storage section.
01 i binary-long.
procedure division using params nums as
int total = Sum(4, 3, 2, 1);
binary-long occurs any
returns 10
returning mysum as binarylong.
perform varying i through nums
add i to mysum
end-perform
end method.
// In Java there is no REF or OUT
option on method parameters.
// Everything is passed by value.
However for a parameter of reference
// type (i.e. not a primitive) it is
the reference itself which is
// passed by value, hence it appears
to be pass-by-reference.
void TestFunc(int x, int y, int z)
{
x++;
y++;
z = 5;
}
int a = 1, b = 1, c = 2;
TestFunc(a, b, c);
System.out.println(a + b + c);
1 2
// 1
// Accept variable number of
arguments
int Sum(int[] nums)
{
int sum = 0;
for (int i = 0; i < nums.length;
i++)
{
sum += i;
}
return sum;
}
//
int[] nums = {1, 2, 3, 4};
int total = Sum(nums);
// returns
10
*> then to call it:
method-id main.
local-storage section.
01 i binary-long.
procedure division.
set i to self::MySum(1, 2, 3, 4)
display i
end method.
/* C# doesn't support optional
arguments/parameters.
Just create two different versions of
the same function. */
void SayHello(string name, string
// Java supports optional parameters
prefix)
void SayHello(String... strings)
*> COBOL doesn't support optional
{
{
arguments/parameters.
Console.WriteLine("Greetings, " +
for (String s : strings)
*> Just create two different versions of the prefix + " " + name);
System.out.println("Greetings, "
same function.
}
+ s);
method-id SayHello.
}
procedure division using value nam as string, void SayHello(string name)
prefix as
{
SayHello("Strangelove", "Dr");
string.
SayHello(name, "");
SayHello("Madonna");
display "Greetings, " prefix space nam
}
end method.
method-id SayHello.
procedure division using value nam as string.
invoke self::SayHello(nam "")
end method.
Strings
Escape
x"0a"
x"09"
"\"
""
sequences
*> line-feed
*> tab
*> backslash
*> quote
Escape sequences
\r
// carriage-return
\n
// line-feed
\t
// tab
\\
// backslash
\"
// quote
Escape sequences
\r
// carriage-return
\n
// line-feed
\t
// tab
\\
// backslash
\"
// quote
String concatenation
01 school string value "Harding" & x"09".
set school to school & "University"
*> school is "Harding
(tab) University"
String
string
school
school
String
String
school
school
Chars
01 letter character.
01 word character occurs any.
set letter to school::Chars(0)
letter is H
set letter to type Convert::ToChar(65)
letter is A
set letter to 65 as character
same thing
set word to school::ToCharArray
word holds Harding
Chars
char letter = school[0];
letter is H
letter = Convert.ToChar(65);
letter is A
letter = (char)65;
same thing
char[] word = school.ToCharArray();
word holds Harding
*>
*>
*>
concatenation
school = "Harding\t";
= school + "University"; //
is "Harding (tab) University"
concatenation
school = "Harding\t";
= school + "University"; //
is "Harding (tab) University"
Chars
// char letter = school.charAt(0);
// letter is H
// letter = (char)65;
// letter is A
//
char[] word = school.toCharArray();
// // word holds Harding
*>
String literal
01 msg string value "File is c:\temp\x.dat".
String literal
string msg = @"File is c:\temp\x.dat";
// same as
string msg = "File is c:\\temp\\x.dat";
String literal
String msg = "File is
c:\\temp\\x.dat";
String comparison
01 mascot string value "Beatles".
if mascot = "Beatles"
true
if mascot::Equals("Beatles")
true
if mascot::ToUpper::Equals("BEATLES")
true
if mascot::CompareTo("Beatles") = 0
true
*>
*>
*>
*>
Substring
set s to mascot::Substring(1, 3) *> s is
"eat"
String comparison
string mascot = "Beatles";
if (mascot == "Beatles")
// true
if (mascot.Equals("Beatles"))
// true
if (mascot.ToUpper().Equals("BEATLES"))
// true
if (mascot.CompareTo("Beatles") == 0)
// true
Substring
s = mascot.Substring(1, 3))
"eat"
String comparison
String mascot = "Beatles";
if (mascot == "Beatles")
// true
if (mascot.contentEquals("Beatles"))
// true
if
(mascot.toUpperCase().contentEquals("
BEATLES")) // true
if (mascot.compareTo("Beatles") == 0)
// true
// s is
Substring NB this is different
behaviour to C#, startIndex endIndex
Replacement
String s = mascot.substring(1, 3);
s = mascot.Replace("Beatl", "Monke")) // // s is "ea"
s is "Monkees"
Split
Replacement
Split
01 names string value
s = mascot.replace("Beatl", "Monke");
"John,Paul,George,Ringo".
string names = "John,Paul,George,Ringo"; // s is "Monkees"
01 parts string occurs any.
// One name in each slot
Split
set parts to names::Split(",")
string[] parts =
names.Split(",".ToCharArray());
String names =
Date to string
"John,Paul,George,Ringo";
01 dt type DateTime value new DateTime(1973, Date to string
// One name in each slot
10, 12).
DateTime dt = new DateTime(1973, 10,
String[] parts = names.split("',");
01 s string.
12);
set s to dt::ToString("MMM dd, yyyy") *>
string s = dt.ToString("MMM dd, yyyy"); Date to string
Oct 12, 1973
// Oct 12, 1973
java.util.Date dt = new
java.util.Date();
int to string
java.text.SimpleDateFormat
int to string
01 x binary-long value 2.
dateformatMMDDYYYY =
01 y string.
int x = 2;
new
set y to type x::ToString
*> x is "2"
string y = x.ToString();
// y is "2" java.text.SimpleDateFormat("MMddyyyy"
);
string to int
StringBuilder nowMMDDYYYY =
string to int
01 x binary-long.
new
set x to type Convert::ToInt32("-5")
*> x int x = Convert.ToInt32("-5");
// x StringBuilder(dateformatMMDDYYYY.form
is -5
is -5
at(dt));
s = "Today is " + nowMMDDYYYY;
Mutable string
Mutable string
int to string
01 buffer type System.Text.StringBuilder
value new
System.Text.StringBuilder buffer =
int x = 2;
System.Text.StringBuilder("two ").
new System.Text.StringBuilder("two
String y = Integer.toString(x);
invoke buffer::Append("three")
");
// y is "2"
invoke buffer::Insert(0, "one ")
buffer.Append("three ");
String to int
invoke buffer::Replace("two", "TWO")
buffer.Insert(0, "one ");
display buffer
*> Prints "one TWO buffer.Replace("two", "TWO");
String minusFive = "-5";
three"
Console.WriteLine(buffer);
// Prints int z = new
"one TWO three"
Double(minusFive).intValue();
//
x is -5
Replacement
set s to mascot::Replace("Beatl", "Monke")
*> s is "Monkees"
Mutable string
java.lang.StringBuilder buffer =
new
java.lang.StringBuilder("two ");
buffer.append("three ");
buffer.insert(0, "one ");
buffer.replace(0, 2, "TWO"); //start,
end, string - different to C#
System.out.println(buffer);
//
Prints "one TWO three"
Exception Handling
*> Throw an exception
// Throw an exception
01 excep type Exception value
Exception up = new Exception("Something
new Exception("Something is really is really wrong.");
wrong.").
throw up;
raise excep
// Catch an exception
*> Catch an exception
try
try
{
set y to 0
y = 0;
compute x = 10 / y
x = 10 / y;
catch excep
*> Argument is optional, no
}
"When" keyword
catch (Exception ex) // Argument is
display excep::Message
optional, no "When" keyword
finally
{
invoke type
Console.WriteLine(ex.Message);
Microsoft.VisualBasic.Interaction::Beep
}
end-try
finally
{
import java.lang.*;
// Throw an exception
Exception up = new
Exception("Something is really
wrong.");
throw new EmptyStackException();
// Catch an exception
try
{
int y = 0;
int x = 10 / y;
}
catch (ArithmeticException ex) //
Argument optional, no "When" keyword
{
System.out.println(ex.getMessage());
}
Microsoft.VisualBasic.Interaction.Beep() finally
;
{
}
System.out.println("\007");
}
Namespaces
*> At the file level
$set ilnamespace "Harding.Compsci.Graphics"
namespace Harding.Compsci.Graphics
{
...
*> The directive can also be set as a project }
*> level to apply the name space to all
classes in the project.
// or
namespace Harding
{
namespace Compsci
// Packages are used to organize
files or public types to avoid
// type conflicts.
// Package constructs can be mapped
to a file system.
package Harding.Compsci.Graphics
...
// package cannot be nested
{
namespace Graphics
{
...
}
}
}
using Harding.Compsci.Graphics;
Classes / Interfaces
Accessibility keywords
public
private
internal
protected
protected internal
static
redefine
Accessibility keywords
public
private
internal
protected
protected internal
static
new
Accessibility keywords
public
private
Inheritance
class-id FootballGame inherits type
Competition.
...
end class.
Inheritance
class FootballGame : Competition
{
...
}
Inheritance
class FootballGame extends
Competition
{
...
}
Interface definition
interface-id IAlarmClock.
...
end interface.
Interface definition
interface IAlarmClock
{
...
}
Extending an interface
interface-id IAlarmClock extends type IClock. Extending an interface
...
interface IAlarmClock : IClock
end interface.
{
...
}
Interface implementation
class-id WristWatch implements type
Interface implementation
IAlarmClock, type ITimer.
...
class WristWatch : IAlarmClock, ITimer
end class.
{
...
}
protected
static
Interface definition
interface IAlarmClock
{
...
}
Extending an interface
interface IAlarmClock extends IClock
{
...
}
Interface implementation
class WristWatch implements
IAlarmClock, ITimer
{
...
}
Constructors / Destructors
class-id SuperHero.
working-storage section.
01 _powerLevel binary-long.
method-id new.
procedure division.
set _powerLevel to 0
end method.
method-id new.
procedure division using value powerLevel
as binary-long.
set _powerLevel to powerLevel
end method.
method-id Finalize override protected.
*> Destructor code to free unmanaged
resources.
end method.
end class.
class SuperHero
{
private int _powerLevel;
public class SuperHero
{
private int _powerLevel;
public SuperHero()
{
_powerLevel = 0;
}
public SuperHero(int powerLevel)
{
this._powerLevel= powerLevel;
}
public void SuperHero()
{
_powerLevel = 0;
}
public void SuperHero(int
powerLevel)
{
this._powerLevel= powerLevel;
}
~SuperHero()
{
// Every class inherits the
// Destructor code to free unmanaged finalize() method from
resources.
// java.lang.Object. The method is
// Implicitly creates a Finalize
called by the garbage
method
// collector when it determines no
}
more references to
}
// the object exist. It should be
overridden to clean-up
// non-Java resources eg closing a
file.
protected void finalize()
{
}
}
Using Objects
01
01
01
01
01
hero type SuperHero value new SuperHero.
hero2 type SuperHero.
obj object.
reader type StreamReader.
myLine string.
set hero::Name to SpamMan
set hero::PowerLevel to 3
invoke hero::Defend("Laura Jones")
invoke type SuperHero::Rest
*> Calling
static method
SuperHero hero = new SuperHero();
SuperHero hero = new SuperHero();
hero.Name = "SpamMan";
hero.PowerLevel = 3;
hero.Name = "SpamMan";
hero.PowerLevel = 3;
hero.Defend("Laura Jones");
SuperHero.Rest();
// Calling static
method
hero.Defend("Laura Jones");
SuperHero.Rest();
// Calling static
method
set hero2 to hero *> Both reference the same SuperHero hero2 = hero;
// Both
object
reference the same object
set hero2::Name to "WormWoman"
hero2.Name = "WormWoman";
display hero::Name *> Prints WormWoman
Console.WriteLine(hero.Name);
//
Prints WormWoman
set hero to null
*> Free the object
hero = null ;
// Free the object
SuperHero hero2 = hero;
// Both
reference the same object
hero2.Name = "WormWoman";
System.out.println(hero.Name);
//
Prints WormWoman
hero = null ;
// Free the object
if hero = null
set hero to new SuperHero
end-if
set obj to new SuperHero
if obj is instance of type SuperHero
display "Is a SuperHero object."
end-if
*> No 'using' construct in COBOL
try
set reader to type
File::OpenText("test.txt")
perform until exit
set myLine to reader::ReadLine
if myLine = null
exit perform
end-if
end-perform
finally
if reader not = null
invoke reader::Dispose
end-if
end-try
if (hero == null)
hero = new SuperHero();
if (hero == null)
hero = new SuperHero();
Object obj = new SuperHero();
if (obj is SuperHero)
{
Console.WriteLine("Is a SuperHero
object.");
}
Object obj = new SuperHero();
if (obj instanceof SuperHero)
{
System.out.println("Is a SuperHero
object.");
}
// Mark object for quick disposal
using (StreamReader reader =
File.OpenText("test.txt"))
{
string line;
while ((line = reader.ReadLine()) !=
null)
{
Console.WriteLine(line);
}
}
// Mark object for quick disposal
FileInputStream fstream = new
FileInputStream("test.txt");
DataInputStream in = new
DataInputStream(fstream);
BufferedReader br = new
BufferedReader(new
InputStreamReader(in));
String line;
while ((line = br.readLine()) !=
null)
{
System.out.println(line);
}
Structures (Value Types)
*> COBOL uses valuetype-id to define a value
type
valuetype-id StudentRecord.
01 #name string public.
01 gpa float-short public.
method-id new.
procedure division using value nam as
string,
gpa as
float-short.
set #name to nam
set self::gpa to gpa
end method.
end valuetype.
class-id a.
method-id main static.
local-storage section.
01 stu type StudentRecord value new
StudentRecord("Bob", 3.5).
01 stu2 type StudentRecord.
procedure division.
set stu2 to stu
set stu2::name to "Sue"
display stu::name
*> Prints Bob
display stu2::name *> Prints Sue
end method.
end class.
// C# uses struct to define a value type //Java doesn't have struct. You may
struct StudentRecord
design a final class
{
// or a simple class to replace
public string name;
struct
public float gpa;
class StudentRecord
{
public StudentRecord(string name,
public String name;
float gpa)
public float gpa;
{
this.name = name;
public StudentRecord(String name,
this.gpa = gpa;
float gpa)
}
{
}
this.name = name;
StudentRecord stu = new
this.gpa = gpa;
StudentRecord("Bob", 3.5f);
}
StudentRecord stu2 = stu;
}
StudentRecord stu = new
stu2.name = "Sue";
StudentRecord("Bob", 3.5f);
Console.WriteLine(stu.name);
//
StudentRecord stu2 = stu;
Prints Bob
Console.WriteLine(stu2.name);
//
stu2.name = "Sue";
Prints Sue
System.out.println(stu.name);
//
Prints Bob
System.out.println(stu2.name);
//
Prints Sue
Properties
class-id MyClass.
working-storage section.
01 _size binary-long private.
*> COBOL also allows you to expose fields
as properties
01 _length binary-long property as
"Length".
01 _width
binary-long property as "Width"
no get.
01 _breadth binary-long property as
"Breadth" no set.
private
private
private
private
int
int
int
int
_size;
_length;
_width;
_breadth;
public int Size
{
get
{
return _size;
}
set
method-id get property #Size.
{
procedure division returning ret as binaryif (value < 0)
long.
{
set ret to _size
_size = 0;
end method.
}
else
method-id set property #Size.
{
procedure division using value val as
_size = value;
binary-long.
}
if val < 0
}
set _size to 0
}
else
set _size to val
public int Length
end-if
{
end method.
get
end class.
{
return _length;
class-id a.
}
method-id main.
set
local-storage section.
{
01 foo type MyClass value new MyClass.
_length = value;
procedure division.
}
add 1 to foo::Size
}
display foo::Size
end method.
public int Width
end class.
{
set
{
_width = value;
}
}
private
private
private
private
int
int
int
int
_size = 0;
_length = 0;
_width = 0;
_breadth = 0;
public int getSize()
{
return _size;
}
public void setSize(int value)
{
if (value < 0)
{
_size = 0;
}
else
{
_size = value;
}
}
public int getLength()
{
return _length;
}
public void setLength(int value)
{
_size = value;
}
public void setWidth(int value)
{
_width = value;
}
public int getBreadth()
{
return _breadth;
}
foo.Size++;
public int Breadth
{
get
{
return _breadth;
}
}
foo.Size++;
Delegates / Events
delegate-id MsgArrivedEventHandler.
delegate void
procedure division using value msg as string. MsgArrivedEventHandler(string message);
end delegate.
event MsgArrivedEventHandler
class-id a.
MsgArrivedEvent;
working-storage section.
01 MsgArrivedEvent type
MsgArrivedEventHandler event static.
*> Delegates must be used with events
method-id main static.
procedure division.
set MsgArrivedEvent to type
Delegate::Combine(MsgArrivedEvent,
new
MsgArrivedEventHandler(self::myMsgArrivedEven
tCallback))
as type MsgArrivedEventHandler
invoke MsgArrivedEvent::Invoke("Test
message")
*> Throws exception if obj is null
set MsgArrivedEvent to type
Delegate::Remove(MsgArrivedEvent,
new
MsgArrivedEventHandler(self::myMsgArrivedEven
tCallback))
as type MsgArrivedEventHandler
invoke self::add_MsgArrivedEvent(
new
MsgArrivedEventHandler(self::My_MsgArrivedEve
ntCallback))
invoke MsgArrivedEvent::Invoke("Test
message 2")
*> Throws exception if obj is null
end method.
method-id myMsgArrivedEventCallback static.
procedure division using value str as
string.
display str
end method.
end class a.
//There is no delegate concept in
Java
//The right-side C# program may be
mimicked
//with reflection technology.
// Delegates must be used with events in
C#
MsgArrivedEvent +=
new
MsgArrivedEventHandler(My_MsgArrivedEven
tCallback);
// Throws exception if obj is null
MsgArrivedEvent("Test message");
MsgArrivedEvent -=
new
MsgArrivedEventHandler(My_MsgArrivedEven
tCallback);
using System.Windows.Forms;
Button MyButton = new Button();
MyButton.Click += new
System.EventHandler(MyButton_Click);
private void MyButton_Click(object
sender, System.EventArgs e)
{
MessageBox.Show(this, "Button was
clicked", "Info",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
Managed COBOL can also handle anonymous delegates
(delegates to anonymous methods) via delegate constructors.
Iterators
class-id sillyCount.
working-storage section.
01 c binary-long value 1 static.
class SillyCount
{
static int c = 1;
method-id main static.
static void Main(string[] args)
local-storage section.
{
01 i binary-long.
// Use foreach to loop through
procedure division using value cmds as
an iterator
string occurs any.
foreach(int i in doCount())
*> Use perform to loop over an iterator
{
perform varying i through self::doCount()
System.Console.WriteLine(i);
display i
}
end-perform
}
end method.
// C# lacks specific syntax to mark
*> Create an iterator by defining a member a method as an iterator
as an iterator
// you have to create a method with
*> Using iterator-id instead of method-id
the correct concrete form
iterator-id doCount static.
// of the IEnumerable interface and
*> The return value if the iterator is
then use the yield return
defined using the
// syntax inside the method.
*> yielding verb
static IEnumerable<int> doCount()
procedure division yielding j as binary{
long.
while (true)
perform until false
{
add 1 to c
c++;
move c to j
// C# uses an implicit
*> Until the iterator is stopped, it
return 'variable' rather than
will yield on
// the named one in COBOL.
*> a goback verb
Yield return returns
goback
// the value as the current
value of the iterator
*> then start again directly after the
yield return c;
goback
*> on the next invocation of the
// then starts immediately
iterator
after the
multiply c by 10 giving j
// yield return on the next
if c < 50
invocation of
goback
// the iterator
else
if (c < 50)
*> Stop iterator means the next
{
goback will
yield return c * 50;
In Java there is no YIELD feature, so
the iterator
implementation has to take care of
state.
Sample to follow...
*> stop the iterator
}
stop iterator
else
goback
{
end-if
// yield break marks the
end-perform
end of the iterator
*> COBOL will implicitly stop iterator at
yield break;
the
}
*> end of the iterator definition.
}
*> In this example – the code never gets
}
here.
}
end iterator.
end class.
Generics - Consuming
*> Consuming a generic method via type
inference
01 result as type Tuple[binary-long binarylong].
*> Parameters are used to infer type
set result to type Tuple::Create(1, 2)
// Consuming a generic method via type
inference
// Consuming a generic method
HashMap<Integer, Integer> result;
System.Tuple<int, int> result;
// Parameters are used to infer type
result = new System.Tuple.Create(1, 2);
result = new HashMap<Integer,
Integer>(1, 2);
*> Consuming a generic collection
//Consuming a generic collection
01 x type List[string] value new
List<string> x = new List<string>();
List[string].
int i;
01 i binary-long.
for(i=0; i<101; ++i)
01 val string.
{
procedure division.
x.Add(i.ToString());
perform varying i from 0 by 1 until i greater }
than 100
foreach(string val in x)
invoke x::Add(i::ToString)
{
end-perform
Console.WriteLine(val);
perform varying val through x
}
display val
end-perform
//Consuming a generic collection
List<String> x = new
ArrayList<String>();
for(Integer i = 0; i < 101; ++i)
{
x.add(i.toString());
}
for(String val : x)
{
System.out.println(val);
}
Generics - Defining
*> Generic class
class-id Point3D using T.
// Generic class
class Point3D<T>
*> With constraints
class-id Point3D using T.
constraints.
constrain T implements type IComputable.
// Generic class with constraints
// Generic class with constraints
class Point3D_c<T> where T : IComputable class Point3D_c <T extends
IComputable>
// Generic interface
interface IComputable<T>
//Generic interface
interface IComputable<T>
// Generic method
public static Point3D<T>
// Generic method
MakePoint3D<T>(T x, T y, T z)
public static <T> Point3D
{
MakePoint3D(T x, T y, T z)
return new Point3D<T>(x, y, z);
{
}
return new Point3D(x, y, z);
}
// Generic method with constraints
public static void MakePoint3D<T>(T x, T // Generic method with constraints
y, T z) where T : IComputable
public static <T extends IComputable>
{
Point3D MakePoint3D(T x, T y, T z)
return new Point3D<T>(x, y, z);
{
}
return new Point3D<T>(x,
y, z);
// Generic value type
}
struct container<T, Y>
{
// No value type in Java, so generic
public T a;
simple class instead
public Y b;
class container<T, Y>
}
{
public T a;
// Generic value type with constraints
public Y b;
struct container<T, Y> where T :
}
IComputable
// No value type in Java, so simple
generic class with constraints
// Generic iterator, use a parameterised class container<T extends
class
IComputable, Y>
class a<T>
{
public static IEnumerable<T> itg(T
// Generic iterator, use a
x)
parameterised class
{
class a<T>
int val = 1;
{
while (val < 50)
public static <T> T itg(T x)
{
{
val++;
int val = 1;
yield return x;
while (val < 50)
}
{
}
val++;
}
return x;
}
}
// Using generic iterator
}
foreach (string dog in
a<string>.itg("Dog"))
System.Console.WriteLine(dog);
for (String dog : a<string>)
System.out.println(dog);
*> Generic interface
interface-id IComputable using T.
*> Generic method
method-id MakePoint3D static public using T.
procedure division using value
x as T y as T z as T
returning ret as type Point3D[T].
*> With constraints
method-id MakePoint3D static public using T.
constraints.
constrain T implements type IComputable.
*> Generic value type
valuetype-id container using T Y.
01 a T public.
01 b Y public.
end valuetype.
*> With constraints
valuetype-id container using T Y.
constraints.
constrain T implements type IComputable.
*> Generic iterator, use a parameterised
class
class-id a using T.
iterator-id itg static.
01 val binary-long value 1.
procedure division using value x as T
yielding y as T.
perform until val = 50
add 1 to val
set y to x *> Just for example!
goback
end-perform
end iterator.
end class.
*> To use, parameterise the class
perform varying thg through type
a[string]::itg("Dog")
display thg
end-perform
// Generic class
class Point3D <T>
Synchronization / Locking
*> Synchronize on an object's monitor, in
this case
*> the current object
sync on self
*> The code here is synchronised
end-sync
// Synchronize on an object's monitor,
in this case
// the current object
lock (this)
{
// The code here is synchronised
// Synchronize on an object's
monitor, in this case
// the current object
synchronized (this)
{
// The code here is synchronised
}
}
Attributes / Annotations
C# terminology : attribute
// Define attributes on a class
[WebService(Description = "MyService")]
[Obsolete]
class MyClass
{
// Define attributes on a
*> Define attributes on a field...
field
01 a binary-long attribute
[XmlAttribute("UpperB")]
XmlAttribute("UpperB")
[Obsolete]
attribute Obsolete static.
long a;
*> Define attributes on a class
class-id MyClass
attribute WebService(name
Description = "My service")
attribute Obsolete.
*> Define attributes on a property...
*> Note that in this case, the attributes
must follow
*> the reserved word PROPERTY.
01 b binary-long property attribute
XmlAttribute("UpperB")
attribute
Obsolete static.
// Define attribute on a
Define attributes on an event...
Note that in this case, the attributes
follow
the reserved word EVENT.
d type fred event
attribute Obsolete static.
// Annotation on a property
@Deprecated
private String prop;
property
private string prop;
[Obsolete]
public string b
{
[return:XmlAttribute("Upper
*>
*>
must
*>
01
// Java terminology : annotation
// Annotation on a class
@Author(name = "Benjamin Franklin",
date = "3/27/2003")
class MyClass
{
// Define attribute on a field
@Deprecated
long a;
@Deprecated
public String getb (){ return
prop; }
@Deprecated
public void setb(String value) {
prop = value; }
B")]
get { return
prop; }
[value:XmlAttribute("UpperB
// Annotation on a method
@SuppressWarnings("unchecked")
public void main()
{
}
")]
*> Define attributes on a method...
method-id main
attribute Obsolete static.
procedure division.
move 999 to a
display a
end method.
*> Define attributes on a method parameter
and return type
method-id stat static.
procedure division using l1 as binary-long
attribute
CLSCompliant(true)
attribute
MarshalAs(3)
returning l2 as binarylong
attribute
CLSCompliant(true)
attribute
MarshalAs(2).
move 999 to a
display a
set d to null
end method.
set { prop =
value; }
}
// Define attribute on an
event
[Obsolete]
public event fred d;
// Define attribute on a
method
[Obsolete]
public void main()
{
}
// Define attributes on
parameters and returns
[return:CLSCompliant(true)]
[return:MarshalAs(2)]
public long
Stat([CLSCompliant(true)][MarshalAs(3)]l
ong l1)
{
return 12;
}
*> Define attributes on a property...
method-id set property prop attribute
property
Obsolete static.
procedure division using l1 as binary-long.
move l1 to a
end method.
value; }
end class.
// Define attributes on a
*> Define attribute on a delegate...
delegate-id fred attribute Obsolete.
procedure division using l1 as binary-long.
end delegate.
// Define attributes on a
[Obsolete]
public string b
{
set { prop =
}
delegate
[Obsolete]
public delegate void
fred(long l1);
}
Beginning of sample programs
Enumb.cbl
enum-id Action.
78 #Start.
*> Start is a reserved word
78 #Stop.
78 #Rewind.
78 #Forward.
end enum.
enum-id Stat as "Status".
78 Flunk value 50.
78 Pass value 70.
78 Excel value 90.
// Define an annotation
public @interface MyAnnotation
{
String doSomething();
int doCount();
}
// Use an annotation
@MyAnnotation (doSomething =
"What to do", doCount = 1)
public void myMethod()
{
}
}
end enum.
program-id main.
procedure division.
display type Status::Pass as binary-long *> prints 70
display type Status::Pass
*> prints Pass
end program.
Choices.cbl
program-id a.
working-storage section.
01 age binary-long.
01 greeting string.
01 x binary-long.
01 y binary-long.
01 color string value "turquoise".
01 r binary-long value 0.
01 b binary-long value 0.
01 g binary-long value 0.
01 other-color binary-long value 0.
procedure division.
if age < 20
set greeting to "What's up?"
else
set greeting to "Hello"
end-if
if x <> 100 and y < 5
multiply 5 by x
multiply 2 by y
end-if
evaluate x
when > 5
multiply
when 5
add y to
when < 10
subtract
when other
divide y
end-evaluate
y by x
x
y from x
into x
evaluate color
*> can be any type
when "turquoise"
when "red"
add 1 to r
when "turquoise"
add 1 to b
when "green"
add 1 to g
when other
add 1 to other-color
end-evaluate
end program.
Loops.cbl
program-id loops.
working-storage section.
01 c binary-long value 0.
01 names string occurs any.
01 s string.
01 i binary-long value 0.
procedure division.
*>Pre-test loops:
perform until c >= 10
*> No WHILE keyword
add 1 to c
end-perform
perform varying c from 2 by 2 until c > 10
display c
end-perform
*> Post-test loops:
perform with test after until c >= 10
add 1 to c
end-perform
*>Array or collection looping
set content of names to ("Rod", "Jane", "Freddy")
perform varying s through names
display s
end-perform
*>Breaking out of loops:
perform until false
if i = 5
exit perform
end-if
display i
add 1 to i
end-perform
*>Continue to next iteration:
perform varying i from 0 by 1 until i >= 5
if i < 4
exit perform cycle
end-if
display i
end-perform
end program.
Arrays.cbl
program-id arrays.
working-storage section.
01 nums binary-long occurs any. *> value 1, 2, 3.
01 names string occurs 5.
*> 5 is the size of the array
*> Can also do:
*> 01 names string occurs any.
01 names2 string occurs 7.
01 twoD float-short occurs any, any.
01 jagged binary-long occurs any, occurs any.
01 rows binary-long value 3.
01 cols binary-long value 10.
procedure division.
set content of nums to (1 2 3 4)
*> Resets the contents of the array (optionally
changing the size)
set size of names to 5
*> Create an array lf length 5
set names(1) to "Rod"
*>set names(6) to "Jane"
System.IndexOutOfRangeException
*> first element indexed as 1
*> throws
*> COBOL cannot directly resize an array - use copy
invoke type Array::Copy(names, names2, names::Length)
*> or else:
invoke names::CopyTo(names2, 0)
set size of twoD to rows, cols
set size of jagged to 3
set size of jagged(1) to 5
set jagged(1, 5) to 5
end program.
Functions-a.cbl
class-id FunctionsA.
method-id main static.
local-storage section.
01 a binary-long value 1.
01 b binary-long value 1.
01 c binary-long. *> c doesn't need initializing
01 total binary-long.
procedure division.
invoke self::TestFunc(a, b, c) *> or invoke self::TestFunc(value a,
reference b, output c)
display a space b space c
set total to function sum(4, 3, 2, 1) *> returns 10
invoke self::SayHello("Robert" "Mr.")
invoke self::SayHello("Robert")
end method.
method-id TestFunc static.
procedure division using value x as binary-long, reference y as binarylong, output z as binary-long.
add 1 to x, y
move 5 to z
end method.
*> COBOL doesn't support optional arguments/parameters.
*> Just create two different versions of the same function.
method-id SayHello static.
procedure division using value name1 as string, prefix as string.
display "Greetings, " prefix space name1
end method.
method-id SayHello static.
procedure division using value name1 as string.
invoke self::SayHello(name1 "")
end method.
end class.
Functions-b.cbl
class-id FunctionsB.
method-id main static.
local-storage section.
01 i binary-long.
procedure division.
set i to self::mySum(1, 2, 3, 4)
display i
end method.
method-id mySum static.
local-storage section.
01 i binary-long.
procedure division using params nums as binary-long occurs any
returning mysum as binary-long.
perform varying i through nums
add i to mysum
end-perform
end method.
end class.
Strings.cbl
program-id Strings.
*> x"0d" *> carriage-return
*> x"0a" *> line-feed
*> x"09" *> tab
*> "\"
*> backslash
*> ""
*> quote
working-storage section.
*> Chars
01 letter character.
01 word
character occurs any.
01 school string value "Harding" & x"09".
*> String literal
01 msg
string value "File is c:\temp\x.dat".
01 mascot string value "Beatles".
01 names string value "John,Paul,George,Ringo".
01 parts string occurs any.
01 dt
type DateTime value new DateTime(1973, 10, 12).
01 s
string.
01 x
binary-long.
01 buffer type System.Text.StringBuilder value new
System.Text.StringBuilder("two ").
procedure division.
*> string concatenation
set school to school & "University" *> school is "Harding (tab)
University"
set letter to school(1:1)
*> letter is H
set letter to type Convert::ToChar(65) *> letter is A
set letter to 65 as character
*> same thing
set word to school::ToCharArray *>word holds Harding
*> string comparison
if mascot = "Beatles"
*> true
display "Pass"
end-if
if mascot::Equals("Beatles") *> true
display "Pass"
end-if
if mascot::ToUpper::Equals("BEATLES")
*> true
display "Pass"
end-if
if mascot::CompareTo("Beatles") = 0
display "Pass"
end-if
*> true
*> Substring
set s to mascot::Substring(1, 3) *> s is "eat"
set s to mascot(2:3)
*> Replacement
set s to mascot::Replace("Beatl", "Monke")
display s
*> s is "Monkees"
*> Split
set parts to names::Split(",")
*> Date to string
set s to dt::ToString("MMM dd, yyyy")
display s
*> string to int
set x to type Convert::ToInt32("-5")
*> Oct 12, 1973
*> x is -5
*> Mutable string
invoke buffer::Append("three")
invoke buffer::Insert(0, "one ")
invoke buffer::Replace("two", "TWO")
display buffer
*> Prints "one TWO three"
end program.
Exceptions.cbl
program-id Exceptions.
working-storage section.
*> Throw an exception
01 exc type Exception value new Exception("Something is really wrong.").
01 x binary-long.
01 y binary-long.
procedure division.
*> Catch an exception
try
set y to 0
divide y into x
catch exc
*> Argument is optional, no "When" keyword
display exc::Message
finally
invoke type Microsoft.VisualBasic.Interaction::Beep
end-try
raise exc
end program.
ClassesInterfaces.cbl
*> Inheritance
class-id FootballGame inherits type Competition.
end class.
*> Interface definition
interface-id IAlarmClock.
end interface.
*> Extending an interface
interface-id IAlarmClock inherits type IClock.
end interface.
*> Interface implementation
class-id WristWatch implements type IAlarmClock, type ITimer.
end class.
interface-id IClock.
end interface.
interface-id ITimer.
end interface.
class-id Competition.
end class.
ConstructorsDestructors.cbl
class-id SuperHero.
working-storage section.
01 memberPowerLevel binary-long.
method-id new.
procedure division.
set memberPowerLevel to 0
end method.
method-id new.
procedure division using value powerLevel as binary-long.
set memberPowerLevel to powerLevel
end method.
method-id Finalize override protected.
*> Destructor code to free unmanaged resources.
*> Implicitly creates a Finalize method
end method.
end class.
UsingObjects.cbl
program-id UsingObjects.
working-storage section.
01 hero
type SuperHero value new SuperHero.
01 hero2 type SuperHero.
01 obj
object.
01 reader type StreamReader.
01 myLine string.
procedure division.
*> No "With" construct
set hero::Name to "SpamMan"
set hero::PowerLevel to 3
invoke hero::Defend("Laura Jones")
invoke type SuperHero::Rest
*> Calling static method
set hero2 to hero
*> Both reference the same object
set hero2::Name to "WormWoman"
display hero::Name
*> Prints WormWoman
set hero to null
*> Free the object
if hero = null
set hero to new SuperHero
end-if
set obj to new SuperHero
if obj is instance of type SuperHero
display "Is a SuperHero object."
end-if
*> No 'using' construct in COBOL
try
set reader to type File::OpenText("test.txt")
perform until exit
set myLine to reader::ReadLine
if myLine = null
exit perform
end-if
end-perform
finally
if reader not = null
invoke reader::Dispose
end-if
end-try
end program.
class-id SuperHero.
working-storage section.
01 #Name string property.
01 PowerLevel binary-long property.
method-id Defend.
procedure division using value attacker as string.
end method.
method-id Rest static.
end method.
end class.
Structs.cbl
valuetype-id StudentRecord.
01 #name string public.
01 gpa float-short public.
method-id new.
procedure division using value nam as string, gpa as float-short.
set #name to nam
set self::gpa to gpa
end method.
end valuetype.
class-id Structs.
method-id main static.
local-storage section.
01 stu type StudentRecord value new StudentRecord("Bob", 3.5).
01 stu2 type StudentRecord.
procedure division.
set stu2 to stu
set stu2::name to "Sue"
display stu::name
*> Prints Bob
display stu2::name *> Prints Sue
end method.
end class.
Properties.cbl
class-id Properties.
working-storage section.
01 _size binary-long private.
method-id get property #Size.
procedure division returning ret as binary-long.
set ret to _size
end method.
method-id set property #Size.
procedure division using value val as binary-long.
if val < 0
set _size to 0
else
set _size to val
end-if
end method.
end class.
class-id a.
method-id main static.
local-storage section.
01 foo type MyClass value new MyClass.
procedure division.
add 1 to foo::Size
display foo::Size
end method.
end class.
DelegatesEvents.cbl
delegate-id MsgArrivedEventHandler.
procedure division using value msg as string.
end delegate.
class-id DelegatesEvents.
working-storage section.
01 MsgArrivedEvent type MsgArrivedEventHandler event static.
*> Delegates must be used with events in C#
method-id main static.
procedure division.
set MsgArrivedEvent to type Delegate::Combine(MsgArrivedEvent,
new MsgArrivedEventHandler(self::My_MsgArrivedEventCallback))
as type MsgArrivedEventHandler
invoke MsgArrivedEvent::Invoke("Test message") *> Throws exception if
obj is null
set MsgArrivedEvent to type Delegate::Remove(MsgArrivedEvent,
new MsgArrivedEventHandler(self::My_MsgArrivedEventCallback))
as type MsgArrivedEventHandler
invoke self::add_MsgArrivedEvent(
new MsgArrivedEventHandler(self::My_MsgArrivedEventCallback))
invoke MsgArrivedEvent::Invoke("Test message 2") *> Throws exception if
obj is null
end method.
method-id My_MsgArrivedEventCallback static.
procedure division using value str as string.
display str
end method.
end class.
AnonymousDelegates.cbl
class-id AnoDel.
method-id main static.
local-storage section.
01 d type del.
01 i type impl.
01 s string.
procedure division.
set s to "Hello from local variable"
set i to new impl
set d to new del(i::InstanceMethod)
display d::Invoke("parameter to instance method")
set d to new del(type impl::StaticMethod)
display d::Invoke("parameter to static method")
set d to new del(delegate returning r1 as string
display s
display "In anonymous method 1"
set r1 to "Returned value from anon method 1"
end-delegate)
display d::Invoke("parameter to anonymous method 1")
set d to new del(delegate using s1 as string returning r2 as string
display s1
display "In anonymous method 2"
set r2 to "Returned value from anon method 2"
end-delegate)
display d::Invoke("parameter to anonymous method 2")
end method.
end class.
delegate-id. del.
procedure division using value x as string returning y as string.
end delegate del.
class-id impl.
method-id StaticMethod static.
procedure division using value x as string returning y as string.
display x
display "In static method"
set y to "Returned value from static method"
end method.
method-id InstanceMethod.
procedure division using value x as string returning y as string.
display x
display "In instance method"
set y to "Returned value from instance method"
end method.
end class.
Iterators.cbl
class-id Permute.
*> Takes a command line of a string and finds all
*> permutations of its characters.
method-id main static.
local-storage section.
01 start-str string.
01 s string.
procedure division using value cmds as string occurs any.
perform varying s through self::GetPermutations(cmds(1))
display s
end-perform
end method.
iterator-id GetPermutations static.
01 i binary-long.
01 s string.
procedure division using value str as string yielding res as string.
if str::Length = 1
set res to str
goback
else
perform varying i from 0 by i until i >= str::Length
set s to string::Concat(str::Substring(0, i),
str::Substring(i + 1))
perform varying res through self::GetPermutations(s)
set res to string::Concat(str::Substring(i, 1), res)
goback
end-perform
end-perform
end-if
stop iterator
end iterator.
end class.
GenericsConsuming.cbl
class-id GenericsConsuming.
method-id main static.
local-storage section,
01 x type List[type Tuple[binary-long, string]]
value new List[type Tuple[binary-long, string]].
01 i binary-long.
01 val type Tuple[binary-long, string].
procedure division.
perform varying i from 0 by 1 until i greater than 100
invoke x::Add(type Tuple::Create(i, i::ToString))
end-perform
perform varying val through x
display val::ToString
end-perform
end method.
end class.
GenericsDefinitions.cbl
class-id MessWithPoint3D.
method-id main static.
local-storage section.
01 vertex1 type Point3D[float-long].
01 vertex2 type Point3D[float-long].
procedure division.
set vertex1 to new Point3D[float-long](new ComputableFloat(1)
new ComputableFloat(1)
new ComputableFloat(1))
set vertex2 to new Point3D[float-long](new ComputableFloat(2)
new ComputableFloat(2)
new ComputableFloat(2))
display type Point3D[float-long]::GetDistance(vertex1
vertex2)::GetValue
end method.
end class.
class-id Point3D using T.
working-storage section.
01 _x type IComputable[T].
01 _y type IComputable[T].
01 _z type IComputable[T].
method-id get property x public.
procedure division returning ret as type IComputable[T].
move _x to ret
end method.
method-id get property y public.
procedure division returning ret as type IComputable[T].
move _y to ret
end method.
method-id get property z public.
procedure division returning ret as type IComputable[T].
move _z to ret
end method.
method-id GetDistance public static.
local-storage section.
01 inter type IComputable[T].
procedure division using value startPoint as type Point3D[T]
endPoint
as type Point3D[T]
returning ret as type IComputable[T].
set
set
set
set
inter to startPoint::x::Subtract(endPoint::x)::Square
inter to inter::Add(startPoint::y::Subtract(endPoint::y)::Square)
inter to inter::Add(startPoint::z::Subtract(endPoint::z)::Square)
ret to inter::Sqrt
end method.
*> The parameters of the new method link the type of IComputable to the
*> type of the Point3D class and so fully enforce type safety
method-id new public.
procedure division using value x-in as type IComputable[T]
y-in as type IComputable[T]
z-in as type IComputable[T].
move x-in to _x
move y-in to _y
move z-in to _z
end method.
end class.
interface-id IComputable using T.
method-id #Add public.
procedure division using value toAdd as type IComputable[T]
returning ret as type IComputable[T].
end method.
method-id #Subtract public.
procedure division using value toSubtract as type IComputable[T]
returning ret as type IComputable[T].
end method.
method-id #Square public.
procedure division returning ret as type IComputable[T].
end method.
method-id #Sqrt public.
procedure division returning ret as type IComputable[T].
end method.
method-id GetValue public.
procedure division returning ret as T.
end method.
end interface.
class-id ComputableFloat implements type IComputable[float-long].
working-storage section.
01 my-value float-long.
method-id new public.
procedure division using value in-value as float-long.
move in-value to my-value
end method.
method-id #Add public.
local-storage section.
01 inter float-long.
procedure division using value toAdd as type IComputable[float-long]
returning ret as type IComputable[float-long].
compute inter = toAdd::GetValue + my-value
set ret to new ComputableFloat(inter)
end method.
method-id #Subtract public.
local-storage section.
01 inter float-long.
procedure division using value toAdd as type IComputable[float-long]
returning ret as type IComputable[float-long].
compute inter = my-value - toAdd::GetValue
set ret to new ComputableFloat(inter)
end method.
method-id #Square public.
local-storage section.
01 inter float-long.
procedure division returning ret as type IComputable[float-long].
compute inter = my-value * my-value
set ret to new ComputableFloat(inter)
end method.
method-id #Sqrt public.
local-storage section.
01 inter float-long.
procedure division returning ret as type IComputable[float-long].
set inter to function sqrt(my-value)
set ret to new ComputableFloat(inter)
end method.
method-id GetValue public.
procedure division returning ret as float-long.
move my-value to ret
end method.
end class.
Synchronization.cbl
class-id Account.
working-storage section.
01 balance binary-long.
01 r type Random value new Random.
method-id new.
procedure division using value init as binary-long.
move init to balance
end method.
method-id Withdraw.
procedure division using value amount as binary-long returning ret as
binary-long.
*> This condition will never be true unless the lock statement
*> is commented out:
if balance > 0
display "< 0"
raise new Exception("Negative Balance")
end-if
sync on self
if balance >= amount
display "In critical section"
*>display "Balance before Withdrawal : " balance
*>display "Amount to Withdraw
: -" amount
compute balance = balance - amount
*>display "Balance after Withdrawal : " balance
move amount to ret
else
display "In critical section"
move 0 to ret
end-if
end-sync
end method.
method-id DoTransactions.
local-storage section.
01 i binary-long.
procedure division.
perform varying i from 0 by 1 until i = 100
invoke self::Withdraw(r::Next(1, 100))
end-perform
end method.
end class.
class-id Test.
method-id Main static.
local-storage section.
01 threads type Thread occurs 10.
01 acc type Account value new Account(1000).
01 i binary-long.
procedure division.
perform varying i from 0 by 1 until i = 10
set threads(i + 1) to new Thread(new
ThreadStart(acc::DoTransactions))
end-perform
perform varying i from 0 by 1 until i = 10
invoke threads(i + 1)::Start
end-perform
end method.
end class.
Attributes.cbl
class-id Attributes
attribute WebService(name Description = "My service")
attribute Obsolete.
*> Define attributes on a field...
local-storage section.
01 a binary-long attribute XmlAttribute("UpperB")
attribute Obsolete static.
*> Define attributes on a property...
*> Note that in this case, the attributes must follow
*> the reserved word PROPERTY.
01 b binary-long property attribute XmlAttribute("UpperB")
attribute Obsolete static.
*> Define attributes on an event...
*> Note that in this case, the attributes must follow
*> the reserved word EVENT.
01 d type fred event
attribute Obsolete static.
*> Define attributes on a method...
method-id main
attribute Obsolete static.
procedure division.
move 999 to a
display a
end method.
*> Define attributes on a method parameter and return type
method-id stat static.
procedure division using l1 as binary-long
attribute CLSCompliant(true) *> method
parameters
attribute MarshalAs(3)
returning l2 as binary-long
attribute CLSCompliant(true) *> return type
attribute MarshalAs(2).
move 999 to a
display a
set d to null
end method.
*> Define attributes on a property...
method-id set property prop attribute Obsolete static.
procedure division using l1 as binary-long.
move l1 to a
end method.
end class.
*> Define attribute on a delegate...
delegate-id fred attribute Obsolete.
procedure division using l1 as binary-long.
end delegate fred.
This article was written at the time of the Visual COBOL R4 release (GA June 2011).
This sample code is supplied for demonstration purposes only on an "as is" basis and "is for use at
your own risk".
Download