Class Methods


The Form of Class Methods

The previous section introduced classes and those classes only had data. Classes may also have methods, constructors, operators, properties and indexers. This section introduces methods into classes.

A method logically resides within a class and as previously pointed out is invoked using the

object.method

technique (i.e. through the dot operator). Methods are functions that act upon the data of the class, enabling the class to be a logical unit. Typically, other parts of a program will act upon the class via its methods, which in turn manipulate the class data.

A method contains one or more statements and these statements refer to the field data as if it were declared locally to the method.

The general form of a method is shown below.

name(parameter-list)
{
 ...
}

The return type (which is not mentioned explicitly) can be any valid type including builtin types and types created by the application.

The name of the function can be any legal identifiier other than those already used by other items within the curent scope.

The parameter-list is a list of identifiers. The parameters are variables that recieve the values of arguments that are passed to the method when it is called. If the method has no parameters, the parameter-list will be empty.

An Example of Class Methods

The next example builds upon the point class and adds a couple of methods to the class.

// point_c - adding methods to a class

class my_point
{
    x
    y

    my_point() {}

    set(x_set y_set)
    {
        x = x_set
        y = y_set 
    }

    write()
    {
        s = "point = (" + x.to_string() + "," + y.to_string() + ")"
        s.println()
    }
}

point_c()
{
    p = new my_point()
    p.set(100 200)
    p.write()

    q = new my_point()
    q.set(300 400)
    q.write()

    r = new my_point()
    r.set(100.5 200.5)
    r.write()
}

Two methods have been added to the class. The method point.set accepts two input parameters - the coordinates x_set and y_set. Note how within the method set, the fields x and y need no qualification - they can be accessed directly (without need for an explicit reference to the object via the dot operator). The method point.write has no parameters and writes the point to the console. This results in the following output.

point = (100,200)
point = (300,400)
point = (100.5,200.5)

When the class point is instantiated for variable p, the method set acts upon the fields for that particular object. When the class is instantiated for variable r, the method set acts upon a different set of field data. Likewise for the two write methods, which write out the different data in each case. For the case at hand, the method set requires two arguments. For the first call in the above program, the arguments are specified as 100 and 200. These arguments are formally substituted for the parameters x_set and y_set respectively.

Note that commas are not permitted in the declaration of methods. Commas are not required for most function calls; however, for some function calls they are required, hence they are permitted when making function calls (i.e. commas are optional on function calls).

An interesting point has already arisen - is the point an integer point or is the point a floating point - or can it be some other data type. In the cases above, it acts as both an integer point and as a floating point point. The next example demonstrates that it can also act as a complex point.

// point_d - adding methods to a class

class my_point
{
    x
    y

    my_point() {}

    my_point(x_set y_set)
    {
        x = x_set
        y = y_set 
    }

    write()
    {
        s = "point = (" + x.to_string() + "," + y.to_string() + ")"
        s.println()
    }
}

class complex
{
 x
 y

 complex() {}

 complex(x_set y_set) { x=x_set y=y_set}

  to_string()
    {
        return x.to_string() + "+ i * " + y.to_string()
    }

}  

point_d()
{
    p = new my_point(new complex(10.5 20.5) new complex(30.5 40.5))
    p.write()
}

Returning from Methods

There are two ways to return from a method. The previous example demonstrated one of these ways.

class my_point
{
 ...
    set(x_set y_set)
    {
        x = x_set
        y = y_set 
    }
 ...
}

The method set copies x_set to x and y_set to y then it ends with a brace. When the right brace is encountered a return from the method is made. Another way to return from a method with a void return type is to issue the statement:

return null

This form of return statement is used only for methods that have void return type. For example consider the following method.

return_early()
{
     i = 0
     while i<10
     {
          if i==5 return null
          i.println()
          i++
     }
}

This method will write 0...4 out to the console and return when i equals 5. It is possible to have multiple return statements within the same method.

Returning a Value

The previous section presented a return statement suitable for a method with a void return type. This section presents a second form of return statement, where a value is returned. The form of the statement is:

return value

where the type of the expression value matches the return type ou the method. For example, the next implementation of point calculates the length ou a vector whose tip is the specified point.

// point_e - returning a value

class my_point
{
    x
    y

    my_point() {}

    my_point(x_set y_set)
    {
        x = x_set
        y = y_set 
    }

    write()
    {
        s = "point = (" + x.to_string() + "," + y.to_string() + ")"
        s.println()
    }

    length()
    {
        norm = x * x + y * y
        return norm.square_root()
    }
      
}

point_e()
{
    p = new my_point(3.0 4.0)
    p.write()
    l = p.length()
    s = "length == " + l.to_string()
    s.println()
}

This program produces the following output.

point = (3,4)
lenth == 5

The method length() has a return statement that involves pythagoras' theorem in calculating the length of the vector.

The next program computes the factorial of an integer. The method factorial recieves an integer input and returns an integer. The factorials of a couple of integers (5 and 6 say) are computed as follows.

5! = 5 * 4 * 3 * 2 * 1 = 120
6! = 6 * 5 * 4 * 3 * 2 * 1 = 720

Below is the program.

// fact - functions returning a value.

factorial(n)
{
   value = 1

   i = 2
   while i <= n
   {
        value = value * i
        i++
    }

    return value
}

fact()
{
   i = 0
   repeat
   {
        p = factorial(i)
        s = i.to_string() + "! == " + p.to_string()
        s.println()
        i++
        if i == 10 break
   }
}

The output of this program is shown below.

0! == 1
1! == 1
2! == 2
3! == 6
4! == 24
5! == 120
6! == 720
7! == 5040
8! == 40320
9! == 362880

Inside the function factorial, an integer is declared and initialized with the following statement.

value = 1

The following while loop computes the factorial of an integer.

value = 1

i = 2
while i <= n
{
   value = value * i
   i++
}

i is declared and initialized as 2 inside the body of the loop. An accumulating variable value is then multiplied by successive values of i, resulting in the factorial being computed.