Where I want everybody to be after demonstration 3:
- You know that a variable is a storage place in which the computer can keep a numerical value. A variable has a name ("Identifier", "symbol"), and in Java it also has a fixed type. How a variable can be used is determined by the semantics (meaning) of the type.
- You are able to declare local variables inside a method body (for example, the main -method of a Java application)
- You are able to write the main method in such a way that it allocates memory for different kinds of variables, and stores the results of mathematical expressions into those by using the assignment operator =.
- You have seen and used two of the common control structures in programming, namely the if structure and the for structure.
So far, all our programs have been of the simplest kind; they have had only one method which is defined as public static void main(String[] args){ /* statements here */ }. The structure of the compilation unit has been the following:
public class TheNameOfYourProgram { public static void main(String[] args){ /* All that we do at first is written here. */ } }
Agenda for the next step:
We must learn the concept of subroutine, which is called method in Java and object-oriented terminology. (Other names for the same thing are at least subprogram and function).
Some ideas behind the use of subroutines are:
- Programs need to perform some things on a regular basis, and differences between each occasion are small. Let us not produce new code for every time, but rather re-use one piece of code that does almost the same thing.
Kinds of subroutines:
- the simplest kind of thing to perform in a subroutine is something that is always exactly the same, like printing a user's guide or the program's version number on the console.
- subroutine becomes more useful via parameterization: You give some input to the subroutine, and it works differently according to its parameters. For example, you might want to print only one paragraph of a user's manual, depending on a parameter called paragraphToBePrinted
- even more useful is a subroutine that computes a new value based on parameters. This kind of a subroutine works much like a mathematical function. Consider the mathematical function "Compute distance of a 2-dimensional coordinate (x,y) from the center of the coordinate system". It gets "x" and "y" as parameters, and it yields "distance" which is computed as "square root of (x^2 + y^2)" every time, regardless of what values the parameters "x" and "y" are given on each time. Terminology: We could say that the subroutine "distance" is called or invoked or activated with specific values to its parameters, "x" and "y", and after computation the subroutine returns what is mathematically defined to be "distance of (x,y) from (0,0)". Parameters and the promise of what is returned is called the interface of the subroutine. In order to use a subroutine/function/method/call-it-whatever, you don't have to know how it is programmed. You just need to know the interface.
- It is often wanted that a subroutine has "side effects" that alter the overall state of the program. For these subroutines, you give object references as parameters, and the subroutine may alter the objects.
- In object oriented design, we use subroutines that are called methods; their purpose can be any of the above, and usually they also alter the internal, hidden, state of an object, on which they operate. The publically available methods of an object determine the interface of the object. An object belongs to a class of objects; each class has a different interface, but it is the same for all objects of the same class.
In this demonstration, we shall be making programs that have more than one static method. This is how programming is, from now on! The structure could be like this, for example:
public class TheNameOfYourProgram { public static void someVerySimpleMethod(){ /* No parameters, no returns (denoted by 'void') */ } public static int someMethodReturningInt(int param1){ /* One integer parameter, one integer return. * Some computation will be written here. * At some point, a return-statement with an expression * yielding an integer value is required */ } public static double yetAnotherMethod(double p1, int p2){ /* Computing "a double value as a function of one double and * an integer". * * At some point, a return-statement with an expression * yielding a double value is required */ } public static void main(String[] args){ /* We call our methods from here. Here are only * some "test cases" to know whether or not our * methods are working at the moment. */ } }
In addition to the concept of subroutine, we take a look at all of the primitive types of Java. We still use only local variables and parameters. We use only two of the control structures: if and for. Later this set must be extended with many others, but we must keep one step as small as possible.
Contents
A cut-down abstract syntax for a method declaration in Java is:
MethodDeclaration = {Modifier} ReturnType MethodName "(" FormalParameters ")" BodyBlock; ReturnType = "void" | Type; FormalParameters = Type Identifier {"," Type Identifier}; MethodName = Identifier; BodyBlock = Block;
Where Type can be any of the types available in Java (either a primitive or an object reference type), Identifier is any name that Java allows. The conventions tell you how things should be named according to the meaning of the things you declare; a method name should begin with a lower-case letter.
For now, let us use exactly two modifiers in each method declaration: public static; of these, public means that we intend the whole world of programmers to be able to call the subroutine from their own applications, and static means that we don't deal with an object's internal state, but rather via parameters and return values only.
Above you can see examples of concrete Java language that follows the syntax. Bare in mind:
- The ReturnType declares what kind of data your method returns as its value. The value can be based on the values of parameters.
- The FormalParameters is a comma-separated list of parameters. Each must have a type and a name. These names are local to the method, and have absolutely no effect in other parts of the program.
Exercise 1:
Take your earlier programs as a starting point. Divide the many statements in main() -methods to smaller pieces, and put each inside a different method. Then call the methods from the main method. See that your program works as you'd expect...
Exercise 2:
Make more useful methods, that use paramters that can have any value. Last time, I urged you to experiment with, for example, the following tasks:
- converting a number of seconds into hours, minutes and remaining seconds in the range 0..59 (you'll need integer division operator / and perhaps the modulo % operator, and maybe some helper variables to store intermediate results...)
- Areas of triangles or circles, from elementary math...
- anything that comes to your mind.
Any of these can be made a parameterized method. Make them so, and call them from the main method!
Exercise 3:
Last time:
- "make a program that stores some temperature as Celsius degrees
in a variable of type double and then transforms the temperature to Fahrenheit degrees (stored in another variable of type double). The conversion formula is mathematically the following:
tempFahr = (9/5)*tempCels + 32
Now, put this into a method which you call by:
calcFahrFromCels(2.0);
or similar. Then, using the for-loop, make a program that computes and prints out, one after the other, fahrenheit degrees for celsius temperatures 1.0, 1.1, 1.2, ... 100.0 - no way you'd do this by copy-paste!