Flow Control II: Methods
[Part 4]


In this part we'll look at the last major element of flow control: methods. There's a lot of material to cover in this part, but it is one of the most important areas in object orientated programming. Make sure you understand the material highlighted by the reviews at the end of each set of slides before moving on.


Powerpoint and audio

Further info:

Getting your head around methods is probably the most important bit of learning Java. Methods structure pretty much everything. With this in mind, take some time now to practice by constructing the following:

1) A two-class version of 'Hello World' in which the main method calls a method in a second class that prints the phrase "Hello World" to the screen.

2) As above, but such that the second class' method takes in a String and prints it. Pass it the phrase "Hello World" from the main class using the method call.

3) As above, but get the method to immediately return the String back to the main class, where it is printed out, using this kind of thing in the main method:

String a = yourObject.yourMethod("Hello World");
System.out.println(a);

This may seem pointless, but getting used to bouncing around variables like this will build up all the skills you need to move forward with methods.


Quiz:

Given the following three classes:


public class Point {
   double x = 100.0;
}



public class PointMaker {

   double minX = 0.0;
   double maxX = 1000.0;
   double minY = 0.0;
   double maxY = 1000.0;

   Point makePoint(double x, double y) {

      if (((x > minX) && (x < maxX)) &&
         ((y > minY) && (y < maxY))) {

         return new Point();

      } else {

         return null;

      }
   }
}

public class GIS {
   public static void main (String args[]) {

      PointMaker pm = new PointMaker();
      Point pt1 = pm.makePoint(-10, -10);
      System.out.println(pt1.x);

   }
}

In the above, at the System.out.println line, pt1.x ______________.

  1. is 0.0
  2. is 100.0
  3. is null
  4. doesn't exist, and if you try to use it, you're dancing with the little demons that break code

Correct! pt1 is null, which means that the primitive x that should be inside it, doesn't yet exist. If you try and run this code it will break at the System.out.println line. Note that it is perfectly formally ok to have a method return null instead of an object (not instead of a primitive though -- as primitive labels can't take null the compiler will stop you trying to return it). Practically speaking you can check whether an object you get back from somewhere is null, by using code like:
 
if (pt1 == null) {
or
if (pt1 != null) {
 
However, in general it isn't a very advisable thing to return from methods. We'll look at how to handle problems within methods, like the 'off the map' problem above, later in the course when we look at 'Exceptions'.


Further info:

What Java calls "methods", other languages call "procedures", "functions", or "subroutines" -- each with their own terminology and ways of handling the passing of variables. In general, when talking about these independent of any language, we refer to them as "procedures".

The development of procedures was a major step forward in computer languages. When computer languages like Java were first developed, they just stepped through a set of things to do from beginning to end, so-called "non-structured imperative programming" (languages like Java are still referred to as "imperative", because they still step through a line of instructions about what to do one at a time, to an extent). Code was often repeated and structured using the command goto to jump about in the code, but this resulted in for(;;) System.out.print ("horrible,"); code.

In the 60's people started to develop structured programming languages, which included loops, branching statements, and, in the sub-family of procedural programming languages, procedures. These were given a considerable boost by a famous* paper by Edsger Dijkstra called "Go To Statement Considered Harmful" (online). In combination these advances led the way directly to object orientated programming.

*In some circles. Not normal people, obviously. Dijkstra's no Paris Hilton.

Powerpoint and audio


Quiz:

Given the code below:

public class ArrayTools {

   double[]]] addOneToCells(double[][] arrayIn) {
      for (int i = 0; i < arrayIn.length; i++) {
         for (int j = 0; j < arrayIn[0].length; j++) {
            arrayIn[j][i]++;
         }
      return arrayIn;
      }
   }

}



public class ArrayUser {
   public static void main (String args[]) {

      double[][] array1 = {{20, 3.0},{4.0,2.0}};
      ArrayTools at = new ArrayTools();
      array1 = at.addOneToCells(array1);

   }
}

What will stop this code compiling and running is _____________.

  1. the index used in the condition of the second dimension loop
  2. the indices in the line arrayIn[j][i]++;
  3. the return type of addOneToCells
  4. the fact that one of the array values is mistyped as an int (20) rather than a double (2.0)
  5. all of these horrors

Correct! This is terrible code, but lots of the terrible coding is especially awful because it won't stop this example running. Use of 0 in (int j = 0; j < arrayIn[0].length; j++) is fine as long as we're expecting regular arrays, but won't work if we have arrays of different lengths in the second dimension. The fact that we have arrayIn[j][i]++; not arrayIn[i][j]++; won't stop this example running (and, as it happens, correctly), because we have a square array, but if the array wasn't square it would break the code by running off the end of the shorter length. The fact that there's a missing decimal place in 20 in the array doesn't matter as far as the computer cares -- it will do an implicit cast. However, what will stop the code compiling, and therefore running, is the fact that the return type is mistyped as double[]]], not double[][].

The main thing to take from this horrorshow is that you can't rely on the compiler and interpreter to catch all of your issues. You also have to carefully think through how to test your methods. Here, for example, we should be using a non-square array, ideally an irregular one, and printing out what goes in and comes out. We'll talk more about testing later in the course, but for now you should get used to thinking about this kind of test.


Powerpoint and audio

Further info:

We've seen two separate structures for classes which are of key importance: the main class, with an constructor to avoid issues of static contexts, and the data storage class with its set and get methods. Just so you have a copy of an example that uses both, which you can use as a template, here's two classes that work together, combining both structures: MainTemplate.java and IntStorage.java.

In computer programming, we might refer to the public methods of a class as its interface, though we have to be a little careful in Java as Java also uses the term for something related, but more specific (as we'll see in the next part). The idea of having a trusted and checkable set of entry points to a piece of code is an important one, and most large scale systems (including, for example, the Windows operating system) hang together by their use of the interface concept, each component communicating with another through trustworthy interfaces.

While we're on the subject of restrictions, a quick additional piece of info on 'toolkit' classes, like the Math class. Quite often, these will have their constructors set to private. This may seem odd, as it means you can't turn them into objects, but it is so that you're forced to use their static methods as toolkits straight from the class. Amongst other things, this encourages a consistent pattern of use across all programmers.


Quiz:

Given the code below:

public class MathUser {

   static double a = 0;

   public static void main (String args[]) {

      double a = Math.sqrt(9);
      store(a);

   }

   public void store (double a) {

      this.a = a;

   }

}

What will stop this code compiling and running is _____________.

  1. the fact that the instance variable a is static, but the code trys to make a method variable with the same name
  2. the fact that Math.sqrt is being sent an int
  3. the fact that main is trying to use a non-static method
  4. all of these horrors

Correct! There's nothing to stop you using the name of a static variable for a method or parameter variable, even inside the same class where it might be confusing. The method/parameter level variable would have scope dominance. Math.sqrt isn't polymorphic (it takes in a double), but the JVM will do an implicit cast anyway. The problem is that the 'store' method isn't static, so the main, which is static, can't reference it. If you just wanted to get this code running, you could make 'store' static, but this just delays the issue. Better to rearrange the code to use the new code template.


[Key ideas from this part]
[Homepage]