You are on page 1of 49

Methods 1 - Introduction to methods

Purpose of this lesson:

Basic purpose of methods. Term: call = Execution proceeds to the code in a method. Term: return = Execution of a method finishes and then continues after point of call, possibly using a value form the method. Term: static method = Method requiring no extra object. Term: instance method = Method that operates on the object before the dot.

New Java language features

Static call syntax:

Instance call syntax:

className.methodName( arguments ) object.methodName( arguments )

Basic idea - A named group of statements Verbs


By now you have used a lot of the predefined library methods, and written many main methods. This chapter explains methods in more detail. Java statements are grouped together in methods. Each method must be inside a class. Every method has a name, which starts with a lowercase character and typically is a verb because it does something. Other terms: The idea of method is in every programming language, but different terms are used in many languages. You might have seen terms like function, procedure, or subroutine. We'll use method consistently here, but you will hear programmers using these equivalent terms occasionally.

Business analogy - services provided by an organization


You could think of classes as corresponding to departments in an organization, and methods as being the services they provide. Let's take an example of calling the telephone information service to get someone's phone number. When you make the call, you pass information, the name of the person whose number you want, to the method (information service). This called "method" then does something, and returns a value to you (the desired phone number). Just as you don't have to know how the information service performs its job, you typically don't need to know exactly how a method does its work, unless of course, you are writing it. Hierarchical organization. Computer programs are structured in many ways like an organization -- higher levels rely on others to do much of the work. They "call" on lower levels to do the work, passing them all necessary "arguments". In a similar way, the top level of a computer program, main, often consists largely of method calls, and those methods may in turn call on yet other methods.

Terms: call and return


Call. When a method call is encountered in a program, the program remembers where it was and execution goes to the method (calls the method). After a small amount of initialization, the statements in the method are executed starting at the beginning.

Return. When the end of the method is reached or a

return statement is executed, the method returns to the where it

was called from, and execution continues in the calling method from that point. A method may return a value (eg, parseDouble) or not (showMessageDialog). The call-return terminology is almost universal.

Static (class) methods


Static. This starts with static (also called class) methods because all applications start with the static methodmain, and many of the early library methods that you use are static methods. Static methods are different thaninstance methods because they don't have an extra object passed to them. Instance methods are associated with an object (an "instance" of a class).

Identifying methods
Parentheses follow name. You can identify a method name because it is always followed by left and right parentheses, which may enclose arguments (parameters). If you see a left parenthesis with a name preceding it, it will be a method call or definition, or a constructor (constructors are very similar to methods). In the following example each method name is highlighted. When calling methods outside of the current class, eg, in the Java library, static methods are preceded by the class name (followed by a dot), and instance methods are preceded by an object. When a static method is defined, the keyword "static" will preceded it. The example below has only static methods.

// File : // Purpose: 1 output. // Author : : 2 // Date 3 4 5

methods/KmToMiles.java Convert kilometers to miles. Use JOptionPane for input / Fred Swartz 22 Apr 2006

import javax.swing.*; public class KmToMiles { //============================================================ constants private static final double MILES_PER_KILOMETER = 0.621; //=================================================================

6 main 7 8 9 10 11 12 1

public static void main(String[] args) { //... Local variables String kmStr; // String km before conversion to double. double km; // Number of kilometers. double mi; // Number of miles.

//Note

//... Input kmStr = JOptionPane.showInputDialog(null, "Enter kilometers."); km = Double.parseDouble(kmStr); //... Computation mi = km * MILES_PER_KILOMETER; //... Output JOptionPane.showMessageDialog(null, km + " kilometers is " + mi + " miles."); }

13 }

Notes 1. This defines a method called "main". Everything between the "{" on the end of this line to the matching "}" second from the end is the "body" of the method.

The above code defines the static withKmToMiles.main(.

main method, which someone (eg, the operating system) will call . .).

To do its work, main calls on other methods: showInputDialog, which is defined in the JOptionPane class,parseDouble, which is defined in the Double class, and showMessageDialog, which is also in the

JOptionPaneclass.

Whenever you call a static method in a different class, precede it with the name of the class containing its definition, followed by a dot. If you don't specify the class name, it assumes the method is defined in the current class.

Identifying instance methods


Object precedes. Instance method calls are identified in the following program. Note that they are all preceded by an object reference. This object is used by the methods to do their work. In this case, the objects are strings. In addition to supplying the object's data to the method, the class of the object, eg String, is where the method is defined.

// File : dialog/capitalize/Capitalize2.java // Purpose: Capitalize first letter of each name. Declare with first use. 1 // Author : Fred Swartz - placed in public domain. // Date : 30 Mar 2006 2 import javax.swing.*; 3 public class Capitalize2 { public static void main(String[] args) { //.. Input a word String inputWord = JOptionPane.showInputDialog(null, "Enter a 5 word"); 4 6 7 word. //.. Process - Separate word into parts, change case, put together. String firstLetter = inputWord.substring(0,1); // Get first letter String remainder = inputWord.substring(1); // Get remainder of

String capitalized = firstLetter.toUpperCase() + 8 remainder.toLowerCase(); 9 } 10 } //.. Output the result. JOptionPane.showMessageDialog(null, capitalized);

What's before the dot tells whether it's a class or instance method
What's before the dot? If it's a class name, then it's a static (class) method; if it's an object, it's an instance method. Nothing at front when calling methods in same class. When calling your own methods, you don't have to write anything before the method name. The compiler assumes the same class or object.

Commentary: Why use methods?


For reusable code If you need to do the same thing, or almost the same thing, many times, write a method to do it, then call the method each time you have to do that task. To parameterize code In addition to making reusable code that is the same in all cases, you will often want to use parametersthat change the way the method works. For top-down programming A very useful style of programming is called top-down programming. You solve a big problem (the "top") by breaking it down into little problems. To do this in a program, you write a method for solving your big problem by calling on other methods to solve the smaller parts of the problem. And these methods for solving the simpler problems similarly call on other methods until you get down to simple methods which solve simple problems To create conceptual units Create methods to do something that is one action in your mental view of the problem. This will make it much easier for you to work with your programs. To simplify Because local variables and statements of a method can not been seen from outside the method, they (and their complexity) are hidden from other parts of the program, which prevents accidental errors or confusion.

Methods 2 - Actual arguments (parameters)


Purpose of this lesson:

Left-to-right argument evaluation Term: actual argument = value which is passed in a method call. Term: void method = method that doesn't return a value. Term: value-returning method = method that does return a value.

Terms: actual argument, argument, actual parameter, parameter


The values that are passed to a method are called actual arguments in the Java specification. However, it is very common for them to be called just arguments, actual parameters, or just plain parameters. These terms are so used interchangeably so often that even the Java specification isn't entirely consistent. For a value which is passed in a call I'll try to stick to actual argument or just argument, which are generally regarded as the "best" terms.

Identifying method arguments


When you call a method, you can pass information for it to use. These actual arguments are inside parentheses following the method name. Use commas to separate arguments if there is more than one. The previous program is shown below, but this time the arguments in the calls are highlighted.

1 2 3 4 5 6 7 8 9 10 11 12

// File : // Purpose: output. // Author : // Date :

methods/KmToMilesArgs.java Convert kilometers to miles. Use JOptionPane for input / Fred Swartz 22 Apr 2006

import javax.swing.*; public class KmToMilesArgs { //============================================================ constants private static final double MILES_PER_KILOMETER = 0.621; //================================================================= main public static void main(String[] args) { //... Local variables String kmStr; // String km before conversion to double. double km; // Number of kilometers. double mi; // Number of miles. //... Input kmStr = JOptionPane.showInputDialog(null, "Enter kilometers."); km = Double.parseDouble(kmStr); //... Computation mi = km * MILES_PER_KILOMETER; //... Output JOptionPane.showMessageDialog(null, km + " kilometers is " + mi + " miles."); }

13 }

Argument evaluation
Before a method is called, the arguments are evaluated left-to-right. In the example above most arguments are simple values, except the second argument in the call to showMessageDialog. Before the call can be made, this argument expression must be evaluated by performing the conversions to string and the concatenations.

Void and value-returning methods


A method may return a value. In the example above, and

showInputDialog returns a String parseDoublereturns a double value. These method calls can be used anywhere in an expression where a String or

double value is required. Here they simply provide the value for the right side of an assignment.

void. If a method has a "side effect", but doesn't produce a value, it is called a void method. TheshowMessageDialog method shows something to the user, but doesn't return a value, and is a void method.
When a method is defined, you need to specify the keyword where the main method definition starts.

void if it doesn't return a value. You can see this on line 13

Commentary: Method terminology?


Method = Function = Procedure = Subroutine = Subprogram
The word method is commonly used in Object-Oriented Programming and is used in Java. Every programming language has this idea, but sometimes uses other terms such as function, procedure, subroutine, ... Many programmers,including Java programmers, use these other terms, especially function, but these notes will usemethod, the official Java term.

Method categories
There have been proposals to establish a convention for identifying different categories of methods. This could be used in documentation for example. There are two categories that are well established.

Getter - methods return (ie, get) a value from an object. The value often exists as a simple field in the class, but may also be synthesized when the getter is called. Synonym = Accessor. Those coming from a C++ background will be more familiar with equivalent termaccessor. Naming conventions. The Java naming conventions for getter methods depends on whether the returned value is boolean or not.

o o o

Boolean getter names typically begin with the word "is" or "has", as in

if (x.isVisible()) . . . while (y.hasDescendants()) . . .

All other type getters have names beginning with the word "get", as in

String greeting = z.getText()


Setter methods set a value or property of an object, which might be implemented as a field, but could be implemented in other ways. Return value. Typically setters return no value, but two useful alternatives to void are (1) return the old value, and (2) return this object so that setter calls can be chained. Synonym = Mutator. If you're a C++ programmer, you're probably familiar with the term mutator for this type of method, although in C++ mutator may apply to any function that modifies any aspect of an object. Naming convention. Setter methods should begin with "set", for example,

z.setText("Hello Earthling");
Other categories have been proposed, for example: factory methods, conversion methods, enumerators, listeners, testing, etc.

Methods 3 - Defining a static method


Purpose of this lesson:

Show how to define a method. Explain parts of method header. Term: formal parameter = variable in method which gets the argument value.

New Java language features

Syntax of method header

Method header syntax


A method header is the part of the method definition that occurs at the beginning. The following definition leaves out a few obscure features, but gives the syntax of ordinary method headers. See Syntax Notation to understand how to read the following. methodHeader visibility parameterList returnType = [visibility] ["static"] returnType methodName "(" [parameterList] ")" . = "public" | "private" | "protected" . = parameterDeclaration {"," parameterList} . = "void" | type

parameterDeclaration = type ParameterName .

How to define your own method


The previous program is rewritten below to define a method to convert from kilometers to miles. The method call, and the first line (header) of the method definition are highlighted.

1 2 3 4 5 6

// // // // //

File : methods/KmToMilesMethod.java Purpose: Convert kilometers to miles using a method. JOptionPane IO. Highlight call and method definition header. Author : Fred Swartz Date : 22 Apr 2006

import javax.swing.*; public class KmToMilesMethod { //============================================================ constants private static final double MILES_PER_KILOMETER = 0.621; //================================================================= main public static void main(String[] args) { //... Local variables String kmStr; // String km before conversion to double.

7 8 9 10 //Note 1 11 12 } 13

double km; double mi;

// Number of kilometers. // Number of miles.

//... Input kmStr = JOptionPane.showInputDialog(null, "Enter kilometers."); km = Double.parseDouble(kmStr); //... Computation mi = convertKmToMi(km); //... Output JOptionPane.showMessageDialog(null, km + " kilometers is " + mi + " miles.");

//========================================================= convertKmToMi 14 private static double convertKmToMi(double kilometers) { 2 double miles = kilometers * MILES_PER_KILOMETER; 15 return miles; } 16 }

//Note

Notes 1. 2. Call our own method below to do the conversion. We could have qualified the name with our class name, KmToMilesMethod.convertKmToMi(km), but this is unnecessary when calling a static method in the same class. Altho this method is trivial, just a multiplication, it is good practice to separate the "model", or "logic", from the user interface. As programs become larger, this separation becomes essential.

Anatomy of the
Visibility -

convertKmToMi

method header

We'll take a look at each of the parts of the method header in order.

public, private, or package private static double convertKmToMi(double kilometers) { double miles = kilometers * MILES_PER_KILOMETER; return miles; }

For greatest reliability and flexibility in your programs, you should always give methods the lowest visibility to others that you can.

When you define a method, you should think about who can use it. Generally you want to choose the lowest level of visibility that makes your program usable, either private or the default (package). Here are the four options, from least visible to most visible.

private - If you don't want any other class to use it, declare it private. This is a good choice.
None (package) - If you don't specify anything, the default visibility allows only classes in the same package (directory) to see it. This is a common choice. It's common to use public visibility whenpackage visibility is more appropriate -- I do it myself. The lack of a keyword for package visibility makes it a little harder to read.

protected - Don't use this protected, except in certain cases to let a child class see it. Even
then, its use is controversial.

public - Let's anyone see it. Choose this if you've defined a method that will be used by others outside of your project. Note that main must be declared public so the run-time system can call it.

Class (static) or instance method

private static double convertKmToMi(double kilometers) { double miles = kilometers * MILES_PER_KILOMETER; return miles; }
A method should be declared

static if it doesn't user instance variables or methods. A static method must use

only only parameters, local variables, and static constants, and other static methods in the same class. If the static keyword is omitted, the method will be an instance method. This example uses static, but soon you will learn about instance methods too. Return type

private static double convertKmToMi(double kilometers) { double miles = kilometers * MILES_PER_KILOMETER; return miles; }
Method name

private static double convertKmToMi(double kilometers) { double miles = kilometers * MILES_PER_KILOMETER; return miles; }
Method names should begin with a lowercase letter. Method names are typically verbs, whereas variable names are usually nouns. Parameter(s)

private static double convertKmToMi(double kilometers) { double miles = kilometers * MILES_PER_KILOMETER; return miles; }
Parameters are enclosed in parentheses following the method name. They are also called formal parameters). There is only one parameter in this example - kilometers, but if there are more, they must be separated by commas. The type of each parameter is specified before the name (eg, double). Parameters are local variables that only exist inside the method. They are assigned initial values from the arguments when the method is called. Method body

private static double convertKmToMi(double kilometers) { double miles = kilometers * MILES_PER_KILOMETER; return miles; }
The body of a method is the statements which are executed when the method is called are enclosed in braces following the the method header. Additional local variables may be defined (eg, miles). Return statement

private static double convertKmToMi(double kilometers) { double miles = kilometers * MILES_PER_KILOMETER; return miles; }
A method returns to the caller after it has done what it wants. If the method returns a value (not a void method), it must contain a return statement that specifies a value to return. When execution reaches thereturn statement, control transfers back to the calling method, passing a return value to it. Returning an expression The above example returns the value in the local variable miles. The return statement can be followed by any expression of the appropriate type, not just a single value. For example, this method body could have been written as a single return statement.

private static double convertKmToMi(double kilometers) { return kilometers * MILES_PER_KILOMETER; }

Order of method definitions doesn't matter


If you define multiple methods in a class, you don't have to worry about the order of the definitions, unlike some other languages.

Commentary: Why start with static methods?


Simplicity is the reason. Methods are a common stumbling block for students, so the introduction to them should be as simple as possible. Static methods are common, and are familiar to students in the form of

main. They are easier than instance methods

because there is no object passed whose fields can be referenced without qualification. My feeling is that throwing a lot of OOP stuff at them at the same time that they're trying to understand method parameters and linkage is too much. And it isn't like they don't use static methods (Integer.parseInt(), JOptionPane.show..., Math.max(), System.exit(), ...). Since they need to understand what it means to qualify the method with a class name instead of an object, it seems reasonable to do a short intro to static methods.

Methods 4 - Local variables


Purpose of this lesson:

Local variables are declared within a method.

Local variable lifetime is from method entry to method return. Local variable visibility is only within the method. Local variables have no initial value. Parameter variables are local variables initialized from the argument values.

New Java language features

final modifier to prevent assignment to parameters.

Principles / Style

Don't assign to parameter variables.

Local variables
Now that we've written two methods, them. Variables that are declared in a method are called local variables. They are called local because they can only be referenced and used locally in the method in which they are declared. In the method below miles is a local variable.

main and convertKmToMi, you should know a little more about the variables in

private static double convertKmToMi(double kilometers) { double miles = kilometers * MILES_PER_KILOMETER; return miles; }

Visibility: Only in defining method


No code outside a method can see the local variables inside another method. There is no need, or even possibility, of declaring a local variable with a visibility modifier -- local variables are automatically known only in the method itself.

Lifetime: From method call to method return


Local variables are created on the call stack when the method is entered, and destroyed when the method is exited. You can't save values in local variables between calls. For that you have to use instance variables, which you'll learn about a little later.

Initial value: None


Local variables don't have initial values by default -- you can't try to use their value until you assign a value. It's therefore common to assignment a value to them when they're declared. Compiler error. If you try to use a local variable before it's been assigned a value, the compiler will notice it and give an error message. But the compiler doesn't really know the exact order of execution in a program, so it makes some conservative assumptions. These assumptions can sometimes be too conservative, and there are cases where you must initialize a local variable even though you know it will have a value before it's referenced.

// BAD BAD BAD BAD BAD BAD BAD BAD BAD BAD BAD BAD BAD BAD BAD private static double convertKmToMi(double kilometers) { double miles;

return miles; }

// Won't compile because nothing was assigned to miles.

Parameters are preinitialized local variables


Method parameters are basically implemented as local variables. They have the same visibility (none outside the method) and lifetime (created on method call, destroyed on method return). Preinitialized. The difference is that parameters are initialized from the corresponding argument values.

// Both kilometers and miles are implemented as local variables. private static double convertKmToMi(double kilometers) { double miles = kilometers * MILES_PER_KILOMETER; return miles; }

Style: Don't assign to a parameter


You can assign to a parameter variable, just as you would to a local variable, but this is often considered bad style because it can deceive the casual reader in two ways:

Unexpected meaning change.. Programmers assume parameter variables represent actual argument values. Assigning to parameters breaks that assumption. Doesn't change actual argument. Because formal parameter variables are really local variables, assigning new values to them doesn't have any effect on the actual parameters. However, in some programming languages assignment to a parameter can assign to the corresponding actual parameter (eg, C++ reference parameters). Therefore if you write an assignment to a formal parameter variable, it may mislead the careless programmer with a C++ background. Or the reader may pause and try to decide if you thought you were assigning to the actual argument. In either case it reduces the readability.

Example. The example below shows how a parameter could be reused. The overhead of declaring an extra variable is just about zero, so this really isn't more efficient, and even this small example is astoundingly misleading.

// BAD BAD BAD BAD BAD BAD BAD BAD BAD BAD BAD BAD BAD BAD BAD private static double convertKmToMi(double kilometers) { kilometers = MILES_PER_KILOMETER * kilometers; altho it works. return kilometers; } // BAD - Don't do this,

Style:

final

keyword prevents assignment


final keyword for each parameter. This prevents assignment to the

Some programmers recommend using the

parameter. Few programmers do this because it adds extra clutter, which in a different way reduces the readability. The use of self-restraint in assigning to parameters is usually suffcient, but specifying final isn't a bad idea.

private static double convertKmToMi(final double kilometers) { double miles = kilometers * MILES_PER_KILOMETER;

return miles; }

Commentary: Pass by value / reference / name / ...


By value. There is some confusion about Java parameter passing. Java uses pass-by-value and only pass-by-value. Actual argument values are copied into the formal parameter variables. There's no pass-by-reference. The confusion comes from the fact that, for objects, a reference is passed, but the reference is passed by value(ie, the reference value is copied into the formal parameter variable). From the authors of Java: "There is exactly one parameter passing mode in Java - pass by value - and that helps keep things simple." The Java Programming Language, 2nd ed. by Ken Arnold and James Gosling, section 2.6.1, page 40, 3rd paragraph. Java's simple parameter passing. Altho there are many possible parameter passing features (see C++ for some), the Java authors choose to only include one simple idea - pass-by-value, with no default values or optional parameter (overloading often provides a satisfactory alternative), no variable length parameter lists (added finally in Java 5), no named parameters, no pass-by-reference, no const (a general Java issue) parameters, etc. Of these, the lack of pass-byreference is the most annoying, now that variable length parameters lists have been added. C++ programmers struggle with giving up pass-by-reference. I was upset that this powerful feature was missing, and was sure there must be some way to write swap, the standard test for pass-by-reference.

public void swap(Object a, Object b) { ???? // Exchange a and b in calling program. }


But it can't be done. The fact that you may sometimes be able to change values in an object or data structure that is passed is not the same as being able to change the value of a variable (l-value) passed as an actual argument. I still miss pass-by-reference. There have been frequent proposals to allow multiple method return values, which would solve most of these cases, but these proposals have been rejected by Sun, presumably because an efficient implementation would require a change to the JVM. Some retreaded-from-C++ authors have had a problem giving up pass-by-reference in their texts, and ever more astoundingly, some even believe it is in Java (it took Deitel&Deitel 3 or four editions to figure it out).

Alternatives
Ruby is a relatively new programming language that has a lot of interesting features. If you think C++ or Java are the end points of function evolution, you might be interested in Ruby features, especially what they call "blocks", which are like method objects (sometimes called closures or continuations). It's not that the effect is impossible to achieve in Java, but that Ruby's simple syntax for it means that it makes the programs more, not less, readable to use them. Another feature is Ruby's multiple return values (tuples), which I've also used in an earlier (now extinct) language, Prograph. Once you use multiple return values, is makes shoehorning everything into a single return value very annoying. I've been occasionally reading Thomas's Programming Ruby, and find it very interesting, but I haven't really done anything with Ruby except for a few very simple test programs. What stopped me was that there is no good documentation on writing GUI programs. There are a couple of GUI libraries, but neither had sufficient documentation the last time I looked.

Methods 7 - How call works

Purpose of this lesson:

Examine the method call/return process in more detail. Term: call stack = Memory that is used to save return address and local variables. Term: stack frame = The storage on the call stack that is used by one method.

New Java language features

None.

The table below shows how the call stack changes as calls and returns in the KmToMilesMethods program are made. This shows the first 8 changes to the call stack after main is entered.

Dynamic changes in the call stack memory allocation


The table below shows how the call stack changes as calls and returns in the KmToMilesMethods program are made. This shows the first 8 changes to the call stack after main is entered. There is actually something before main on the call stack, and the library methods that are called call many methods of their own, which isn't shown here because we don't need to know what they call. Stack frame. Each box represents the information that's stored on the call stack for each method. This block of information is often called a stack frame. There is internal information associated with the method, for example, it saves the place to resume execution in the calling method. Each stack frame is labelled with the method name and a list of parameters and local variables that are allocated on the stack. "???" is written when we don't know (or care) what the local variables are that are used by a library method. 1 main args kms miles 2 main args kms miles getDouble prompt str main args kms miles getDouble prompt str showInputDialog ??? 3 4 main args kms miles getDouble prompt str main args kms miles getDouble prompt str parseDouble ??? 5 6 main args kms miles getDouble prompt str 7 main args kms miles main args kms miles convertKmToMi kilometers miles 8

Typical call sequence


1. 2. Evaluate arguments left-to-right. If an argument is a simple variable or a literal value, there is no need to evaluate it. When an expression is used, the expression must be evaluated before the call can be made. Push a new stack frame on the call stack. When a method is called, memory is required to store the following information. o Parameter and local variable storage. The storage that is needed for each of the parameters and local variables is reserved in the stack frame. o Where to continue execution when the called method returns. You don't have to worry about this; it's automatically saved for you. o Other working storage needed by the method may be required. You don't have to do anything about this because it's handled automatically. Initialize the parameters. When the arguments are evaluated, they are assigned to the local parameters in the called method.

3.

4.

5.

Execute the method. After the stack frame for this method has been initialized, execution starts with the first statement and continues as normal. Execution may call on other methods, which will push and pop their own stack frames on the call stack. Return from the method. When a return statement is encountered, or the end of a void method is reached, the method returns. For non-void methods, the return value is passed back to the calling method. The stack frame storage for the called method is popped off the call stack. Popping something off the stack is really efficient - a pointer is simply moved to previous stack frame. This means that the current stack frame can be reused by other methods. Execution is continued in the called method immediately after where the call took place.

Methods 5 - Example with three methods


Purpose of this lesson:

Show definition of multiple methods.

Programming ideas

All code is in methods. Style: The main method often consists largely of method calls. Style: Methods should generally be no larger than one page.

Here is another variation of the program, this time using three methods. Altho there is no real need for these methods in such a small program, large programs are in fact composed of many small methods. It is the essential way that all code is structured. Each of the user-defined method names, both in the call and the definition, is hilited.

One method is void, which means it doesn't return a value. Three methods call other methods. The main program consists mostly of calls to other methods.

Source code
// File : methods/KmToMilesMethods.java // Purpose: Converts kilometers to miles using two methods. // Author : Fred Swartz - placed in public domain // Date : 22 Apr 2006 import javax.swing.*; public class KmToMilesMethods { //================================== ======================= constants private static final double MILES_PER_KILOMETER = 0.621; //================================== ============================ main public static void main(String[]

args) { double kms = getDouble("Enter number of kilometers."); double miles = convertKmToMi(kms); displayString(kms + " kilometers is " + miles + " miles."); } //================================== =================== convertKmToMi // Conversion method kilometers to miles. private static double convertKmToMi(double kilometers) { double miles = kilometers * MILES_PER_KILOMETER; return miles; } //================================== ======================= getDouble // I/O convenience method to read a double value. private static double getDouble(String prompt) { String tempStr; tempStr = JOptionPane.showInputDialog(null, prompt); return Double.parseDouble(tempStr); } //================================== =================== displayString // I/O convenience method to display a string in dialog box. private static void displayString(String output) { JOptionPane.showMessageDialog(null, output); } }

Programming:

Hammurabi v0
Description
This program simulates the functioning of an early agricultural society. It is based on the ancient computer game Hammurabi, named after a Babylonian king (See en.wikipedia.org/wiki/Hammurabi) famous for his laws. He also ran a very authoritarian society in which the peasants were allocated fixed rations of food by the state, as in this game. Goal. The user, who has just become the ruler of a kingdom, wants to make a place in history by having having the largest population of peasants. The simulation lasts five years or until everyone has starved. Grain is the basic resource. Each year, ask the ruler how to use the grain in storage.

How many bushels to feed the people. How many bushels to use as seed for planting next year's crop.

The remaining grain, if any, is saved for the next year in case of a bad harvest. Initial Conditions The Kingdom starts with the following resources: an area of 1000 acres, a population of 100, and with 3000 bushels of grain from the previous harvest.

Food and Population Rules


Each peasant needs a minimum of 20 bushels of grain per year to survive. Starvation. If the ruler doesn't allocate enough food for everyone, some will starve. The population is then reduced by the number of peasants who starved. Immigrants if lots of food. If people receive more than 20 bushels per person, immigrants from neighboring kingdoms will be attracted, resulting in a population increase. Formula. This simple population computation can be made by dividing the total amount of food by the amount needed per person.

k_peasants = food / MIN_GRAIN_TO_SURVIVE


This is inside the where

simulateOneYear method, k_peasants is a static variable representing the

Kingdom's current population, and MIN_GRAIN_TO_SURVIVE is a constant predefined to

be 20. For example, if the ruler allocates 2400 bushels, this will support a population of 2400 / 20, which is 120. This would become the new population.

Agriculture
Seed for Planting. Not all grain can be used for feeding the people. Some must be used to plant next year's crop. It takes two bushels of grain to plant an acre. To plant everything therefore requires 2 * area bushels of grain. Harvest. There are variations in the weather each year. The yield varies from 2 to 6 bushels per planted acre. This number is randomly generated each year.

Continue for 5 years or the entire populatin has starved


The main program gets information from the user/ruler on how to allocate the grain each year, simulates one year, and display the results for that year. It should continue in a loop until the end of the simulation time period or the peasants have starved. The

simulateOneYear method, which takes parameters

for how much grain to use to plant the next crop, and how much grain to feed the population. Extend it to add population. Keep all input/output in the main method. Check for legal values, eg, don't allow the ruler to plant more grain than there is.

Copy these files to start your project


In the spirit of iterative programming, here is a working version, but it doesn't implement all features. Some areas that must be extended are marked with "TODO" (ie, things remaining "to do").

Hammurabi first version


// File : hammurabinoop/Hammurabi0.java // Purpose: Starting point for working on the Hammurabi program. // Author : Fred Swartz - 2007-05-03 -

Placed in public domain. // TODO : * Prompt for amount to feed peasants. // * Check for reasonable values (enough grain, ...). import java.util.*; public class Hammurabi0 { //===================================== ========================== constants private static final int MIN_GRAIN_TO_SURVIVE = 20; private static final int MAX_LAND_FARMABLE_PER_PERSON = 15; private static final int SEED_REQUIRED_PER_ACRE = 2; private static final Scanner in = new Scanner(System.in); //===================================== ========================== variables // Everything prefixed with "k_" is part of the status of a Kingdom. // All "k_" variables should be part of a Kingdom class, but.... private static int k_grain = 3000; // Bushels of grain in storage. private static int k_area = 1000; // Area of kingdom in acres. Note that // k_area isn't used yet, but will be if // you add a check for the total amount // of land that can be planted. private static int k_year = 0; // Years since founding of kingdom. private static int k_harvest = 0; // Last harvest in bushels. private static int k_peasants = 100; // Number of peasants. //===================================== ============================= main public static void main(String[] args) { //... Run the simulation for 5 years or until everyone starves. while (k_peasants > 0 && k_year <= 5) { displayStatus();

// Show status of kingdom every year. int food = promptForFood(); // How much grain should be use for food? int seeds = promptForSeeds(); // How much grain should be used for planting? simulateOneYear(food, seeds); // Simulate effect of feeding and planting. k_year++; // Another year has passed. } //... End of simulation. status. if (k_peasants == 0) { System.out.println("Everyone starved!!!!"); } else { System.out.println("Congratuations, you survived for 5 years!"); } displayStatus(); } //===================================== ===================== displayStatus public static void displayStatus() { System.out.println(" Kingdom status at year " + k_year + ": last harvest = " + k_harvest + "\nTotal grain = " + k_grain + "\nPeasants = " + k_peasants); } //===================================== ===================== promptForFood private static int promptForFood() { //TODO: Ask the ruler how much to feed the people. return 0; } //===================================== ==================== promptForSeeds Show

private static int promptForSeeds() { //.. Ask the ruler how much grain should be used for seed. System.out.println("Exalted Ruler, how many bushels should be planted?"); return in.nextInt(); //... TODO: Check if not enough grain for this request, Reprompt. } //===================================== ==================== simulateOneYear private static void simulateOneYear(int food, int seed) { //... Calculate new population.based on food. k_peasants = food / MIN_GRAIN_TO_SURVIVE; k_grain -= food; // Reduce grain by amount used for seed.

//... Calculate new harvest // 1. How many acres can be planted with seed. // 2. The yield per acre is random (2-6) // 3. Harvest is yield * area planted. int acresPlanted = seed / SEED_REQUIRED_PER_ACRE; k_grain -= seed; // Reduce grain by amount used for seed. // TODO: Check that there are enough people and there is // enough land to actually plant that number of acres. int yieldPerAcre = 2 + (int)(5 * Math.random()); // Number from 2 to 6 k_harvest * acresPlanted; = yieldPerAcre

//... Compute new amount of grain after the harvest. k_grain += k_harvest; // New amount of grain in storage. }

Misc info

Name. Please change the name from Hammurabi to something else. You can also change the basic elements of the game, as long as it remains a oneplayer game trying to rule a civilization. One player. Do not try to make this into a two-player game where there are multiple kingdoms. A twoplayer game would best be done using multiple kingdom objects, which you don't know how to use yet. If you try to build two kingdoms on this static structure it turn into an ugly mess. The Object-Oriented approach to this would be a simple way to make multiple kingdomes. Cooperating. If you want to pair up with someone else on this program, that's fine, but I'll expect a more extensive final program. You should try to keep from stepping on each other's code by writing separate methods.

Extra credit possibilities


This above game omits some interesting aspects. After you have the simple version of the program running as described above, you might want to make it more "realistic" by adding some of the following features.

Better interface. Don't hesitate to make the interface better, use JOptionPane, better output, ... Buying and selling land. Land can be bought from the neighboring kingdoms (or sold back to them) for 20 bushels per acre. The yearly plan that the ruler makes should therefore include how much land to buy/sell in addition to the food and seed allocations. Allowing land to be added is the only way to get the population to really grow. Farming limits. The amount of land that one peasant can farm should be limited to 15 acres. If the population drops, it may not be possible to farm all land. Revolt. If more than 45% of the population starves, there is a revolt which overthrows the ruler, and the game ends. Soldiers. My wife's first reaction was to ask about the soldiers. They could play an important role, but exactly what will be left up to you (eg, suppress revolts, capture land, etc). But perhaps they must be fed better than the peasants. Random events o Rats. Each year, rats eat a random amount

from 0-10% of your grain Plague. There is a 15% chance each year of a plague. If that happens, half the population dies.

Copyleft 2007 Fred SwartzMIT License

Methods 6 - Overloading
Purpose of this lesson:

Explain overloading = multiple methods with the same name.

Programming ideas

The method name is important to the human programmer as the key to describing an action to be performed. It's often useful to do the "same" action, but with different kinds of parameters. The compiler can distinguish methods that have the same name only if they have a different numberand / or type of parameters.

Here is a small program which simply computes the average of three numbers. It uses three overloaded methods to read the numbers. For such a small program you would not use three different methods, of course, but this shows how overloaded methods are defined and used. It's very common for one overloaded method to call another. another variation of the program, this time using three methods. Altho there is no real need for these methods in such a small program, large programs are in fact composed of many small methods. It is the essential way that all code is structured. Each of the user-defined method names, both in the call and the definition, is hilited.

One method is void, which means it doesn't return a value. Three methods call other methods. The main program consists mostly of calls to other methods.

Good practices

Coherence. It's important that all the methods do the "same" thing, so that the program is human comprehensible. All methods sharing the same name should return the same value, have the same side effects, and all be either static or instance methods. The language doesn't require this, but doing otherwise is asking for trouble.

Call each other. Because all overridden methods should be doing the same thing, it is very common for there to be calls from one to another, supplying extra default parameter values as required. Default parameter values. Some programming languages allow you to specify default values for parameters, and if a the parameter is not supplied, the default value is used. Java doesn't have default parameters, but you can easily implement them using overloaded methods.

Example of overloading - averaging three values


// File : methods/avg3/AvgThreeOverloaded.java // Description: Averages three numbers -- meaningless, but // Purpose: Show an overloaded method, getDouble, with three definitions, // differing in the number of parameters. // Issues : Input isn't checked for legality (non-null number) because // the point is to show overloading. // Author : Fred Swartz - 2007-01-11 placed in public domain import javax.swing.*; public class AvgThreeOverloaded { //===================================== ========================= main public static void main(String[] args) { //... Read three numbers using the three different methods. // Using three different methods is only to show overloading. double n1 = getDouble(); double n2 = getDouble("Enter the second number."); double n3 = getDouble("Enter last number.", 0.0, 100.0); double average = (n1 + n2 + n3) / 3.0; displayString("Average is " + average); }

//===================================== ==================== getDouble // I/O convenience method to read a double value. // This version of the getDouble method simply calls on another // version passing it a generic input message. private static double getDouble() { return getDouble("Enter a number"); } //===================================== ==================== getDouble // I/O convenience method to read a double value given a prompt. // This version of getDouble displays the user supplied prompt. private static double getDouble(String prompt) { String tempStr; tempStr = JOptionPane.showInputDialog(null, prompt); return Double.parseDouble(tempStr); } //===================================== ==================== getDouble // I/O convenience method to read a double value in a range. // It builds a new prompt and calls another version to get // the value, looping until a value in the range is found. private static double getDouble(String prompt, double low, double high) { double result; String rangePrompt = prompt + " Value must be in range " + low + " to " + high; //... Read and loop back if the number is not in the right range. do { result = getDouble(rangePrompt); } while (result < low || result

> high); return result; } //===================================== ================ displayString // I/O convenience method to display a string in dialog box. private static void displayString(String output) { JOptionPane.showMessageDialog(null, output); } }

Don't confuse overloading and overriding


This two terms are easily confused because they both have to do with multiple definitions of methods. Better terms would have been nice, but these are what we have. Overloading is making multiple method definitions which differ in the number or types of parameters, as described here. Overriding is redefining a method in a super class, using exactly the same number and types of parameters.

Commentary: Return statements and the single exit fantasy


Structured programming purists. A controversial "rule" used by strict structured programmers is that every method should have only one return statement at the end. Their reasoning is that it is easier to understand control flow when you know exactly where the method returns (the end). The single return issue is often called the single exit issue, and it also applies to use of the continue and breakstatements in loops, which are forbidden by the purists, but allowed by the simplifiers. Simplifiers. Altho a single exit is appealing, code can become quite convoluted with setting and testing additional extra boolean variables which are needed to implement a single exit style. Most programmers probably support the idea that simple readable code in more important than following any arbitrary rule. If coding to achieve a single return means complicating the code, then it's a mistake. Exercise: Change this to single-return style It's fairly easy to rewrite this to use only a single return; try it. And don't use a break statement in the loop because this also violates the single-exit style.

//======================================================= primeFactor // Return a factor of n, or 0 if n is prime. // Uses simple algorithm of dividing by all numbers up to n. // Could improve efficiency many ways. public static int primeFactor(int n) { for (int divisor = 2; divisor < n; divisor++) { if ((n % divisor) == 0) {

return divisor; } } return 0; }

// Divisible implies not prime!

// Must be prime if nothing was able to divide it.

Variations on max() showing several possible return strategies


Problem: Write a method to compute the maximum of two double values. These alternate implementations show that even this simple problem offers several alternatives on where to return. Version 1 - Return immediately This is a straightforward example of returning the value as soon as it's known.

public static double max(double a, double b) { if (a > b) { return a; } else { return b; } }


Version 2 - Single return The orthodox philosophy of Structured Programming is that every method should have only one return at the end. To implement this, use a variable to hold the max value and return it at the end.

public static double max(double a, double b) { double result; if (a > b) { result = a; } else { result = b; } return result; }
This method is clear in either style, but the rigid application of the one-return rule can make some methods very convoluted. The overriding principle that most programmers use is that program flow should be as clear as possible. Version 3 - No need for else when the true part returns.

// Stores the maximum value until the return.

public static double max(double a, double b) { if (a > b) { return a; }

return b; }

// Only executed if comparison was false.

Version 4 - Typical hacker obfuscation The hard-to-read

?: operator is a favorite of programmers who want to impress others. It does result in shorter source

code (but not more efficient execution). Most people don't find this more readable.

public static double max(double a, double b) { return a>b?a:b; }


It could be made more readable with ()s and spacing.

return (a > b) ? a : b;
Library. Of course you should use the predefined methods (Math.max()) rather than writing your own!

Uncaught exceptions moot the issue


The third way to exit a method. The

return statement and the end of the method are not the only ways to return

from a method. Uncaught exceptions are the other way to exit a method.

throw statement exits the method.

Calling any method which throws exceptions many be a point at which the method is exited. If it throws unchecked exceptions, it may not be easy to determine that they are thrown. Any statement which could cause an exception is another potential exit point.

Editor support for showing method exit points


Some editors may highlight method exit points. This is perhaps a better solution than trying to bend the code to fit a particular rule.

Additional Discussion

Multiple return statements (http://www.javapractices.com/Topic114.cjp) Argues that multiple returns, altho subject to abuse, can make code clearer, especially in handling exception cases at the beginning. Multiple Return Statements (http://onthethought.blogspot.com/2004/12/multiple-return-statements.html) Bruce Eckel argues that multiple return statements can make "cleaner" code. If multiple returns are being used in a bad way, enforcing a rule like this probably won't make the programmer write clear code in any case. Code improvement guidelines (http://jroller.com/comments/fra3k/Weblog/code_improvement_guidelines) Argues for single return statements on the basis of clarity, which is curiously the same basis that is used for multiple return statements. Nice argument for multiple return statements in a response to this blog entry (in equals()).

OOP: Defining Value Classes

OOP 1. Introduction to Classes and Objects


Purpose of this lesson:

Overview

o o o o

Classes combine data and methods. A class defines a data type. Advantage: Classes correspond to concepts in the problem domain. Advantage: Classes reduce complexity by increasing coherence and reducing coupling.

Introduce classes to store data in value objects.

Terminology

Instance variable = Variable declared in class outside a method. Typically private. Field = Synonym for instance variable, attribute. Common informal term. Attribute = Synonym for instance variable, field. Often used in the design phase. Property = Synonym for instance variable, field. Common term if field is known publicly.

New Java language features

Declaring fields (instance variables).

Object-Oriented Programming (OOP) concepts


Class = data + methods. Everything (data and methods) in Java is contained in classes. So far you've been using classes to hold methods (main and perhaps a few other static methods). These methods use local variables, which are completely private to the method, and which disappear when the method returns. Historical development. Classes can also be used to store data. Historically, programming languages had something similar to classes for grouping data, usually called structs or records. These were used for storing only data, not methods. Eventually, advantages of combining both data and the methods to work on that data were recognized. Classes model problem. One advantage of encapsulating data and methods in a class is to make programming objects that reflect "objects" in the problem domain. If your problem deals with orders and products, then you'll very likely have classes called Order and Product. Classes reduce complexity. Another advantage of classes is reducing complexity. Complexity limits the size and reliability of programs. Complexity is reduced by increasing cohesion (putting things together that belong together) and reducing coupling (interconnections). The proper use of classes can make large improvements in both of these. Class, object, OOP. The name class was almost universally adopted for programming language structure which combines data and methods, object is used for each instance of a class that is created, and the practices that developed around these ideas is called Object-Oriented Programming (OOP). Value objects - Data-first approach. We'll start with classes that represent data, and then add constructors and methods. Ultimately you will be more concerned with methods than data, and you'll see how (and why) methods are used to completely hide the data implementation.

A class stores the attributes (data) of something

Group values. Classes are used to group a number of related, named, data values associated with an entity. By entity we mean something that is typically a noun when you are talking about a problem you are solving. For example, in a university computing system, you might have a class to represent a student, an instructor, a classroom, a department, a course, a section of a course, .... Student example. The information you would store about students, would be their name, id, etc. We'll keep this example simple and just save name and id information. Declare each field. A class contains declarations of the fields (instance variables, attributes) that hold the data associated with a student. These declarations are like declaring a local variable in a method, except that you will also specify the visibility. We'll start by using the visibility modifier public, which lets anyone see them. For example, the following

Student1 class can be used to represent a student. As you go through these notes, we'll make improvements

to this class.

public class Student1 { public String firstName; public String lastName; public int } id;

A class is a type
Noun. Classes are usually given the name of a noun, and the fields (variables) in it are attributes associated with that noun. Predefined Java classes that you have already used are String, which contains the characters in the string and the length,

JOptionPane, which contains information necessary to produce a dialog box on the screen, etc. These

predefined Java classes are used for the programming infrastructure that you need. Many common infrastructure classes are available in the 3000+ predefined Java library classes. But, of course, these don't address your problems. Business objects. Most classes you define will concern your problem domain, where they represent business objects (Student, TimeOfDay, Order, ...). Declaring business object variables is like declaring any other variable. Use the class name as a type, just as you've used String, int, etc. For example, the following declares two Student1 variables.

Student1 bestInClass; Student1 t;

// This variable references a Student1 object. // And here is another

These don't have values yet, but we'll do that in the next section.

Does your problem require classes or simple variables?


If the data you are working with, for example a temperature, can be expressed as a simple value and the operations on it are all defined by operators, then just use a simple variable for it (int, double, String, ...). Often the data associated with an entity in your problem is not a simple value, but has multiple attributes. Examples showing classes as groups of attributes.

Instead of working with simple temperature numbers, you might have TemperatureMeasurement objects, which have several attributes: the temperature, the time, and the location. A Student class would represent information about a student: name, id, address, ... Each object of this class would have a data about a specific student. A Classroom class would have information about a classroom's building, room number, capacity, whether it has a projector, etc.

Object-Oriented Design involves deciding which classes you need to represent the things (entities) in your problem. For simple programs, you often use only simple variables, but as programs get larger, you will define more and classes to represent the things you are working with.

Similarity to database table


If your are familiar with databases, a class is very similar to a table definition. If you're not familiar with databases, don't worry because these lessons don't assume you are.

OOP 2. Data - Student Class


Purpose of this lesson:

Classes versus objects. How to create objects and assign values to the instance variables (fields). Good practice: One class per file is the standard.

New Java language features

Using

new to create an object.

Referencing fields using dot notation.

One class per file is standard practice


Here is the class again that represents information about a student. Typically there is one class definition per file, so this would be stored in Student1.java.

// File

: oop/dataclass/Student1.java

// Purpose: Information about a student. public class Student1 { public String firstName; // First name public String lastName; public int } id; // Last name // Student id

Class versus object


A class is a template that defines what attributes an object can have. You make one class definition, then create objects of that class using the new keyword. Some analogies might make this clearer. Analogy: Cookie cutter and cookies. A cookie cutter is like a class definition. It isn't a cookie, but can be used to create a cookie. Each cookie can will have the same attributes (shape), but each cookie can have different values for the attributes (type of dough, thickness, ...). Analogy: Dog and Fido. The concept of Dog is like a class, but there are many possible instances of this class, eg, my dog Fido, or your dog Rover.

Analogy: Form stamp and filled out forms. There are rubber ink pad stamps that are used to stamp out a small form. These have been used in several places in my passport, where passport control stamped my passport, then filled out the fields with the date, how long I could stay, etc. The rubber stamp is like a class, defining the fields. The filled out form in each passport are the objects, with specific values for each field.

Use

new

to create a new object

A class defines what fields an object will have when it's created. When a new Student1 object is created, a block of memory is allocated, which is big enough to hold these three fields -- as well as some extra overhead that all objects have.

Student1 tatiana; tatiana = new Student1();


"new" and parentheses To create a new object, write

// Create Student1 object with new.

new followed by the name of the class (eg, Student1), followed by parentheses. Later

we'll see that we can specify arguments in the parentheses when creating a new objects. Default field values - null, zero, false Unlike local variables in a method, fields do have default values (like the default values in arrays). Object references are null, numbers are zero, and booleans are false. Access public fields with dot notation The fields (firstName,

lastName, id) name data which is stored in each object. Another term for field isinstance

variable. All public fields can be referenced using dot notation (later we'll see better ways to access and set fields). To reference a field, write the object name, then a dot, then the field name.

Student1 tatiana; object.

// Declare a variable to hold a Student1

//... Create a new Student1 object for Tatiana. tatiana = new Student1(); // Create a new Student1 object with default values. tatiana.firstName = "Tatiana"; // Set values of the fields. tatiana.lastName = "Johnson"; tatiana.id = 9950842; JOptionPane.showMessageDialog(null, "One student is named: " + tatiana.lastName + ", " + tatiana.firstName);
Awkward? This simple example with one student is somewhat awkward, but we'll get to examples that show real advantages soon.

A class definition is a template for creating objects


A class defines which fields an object has in it. You need to use

new to create a new object from the class by allocating

memory and assigning a default value to each field. A little later you will learn how to write aconstructor to control the initialization. It's not very interesting to create only one object of class, so the following example creates a couple of them.

//

File

: oop/dataclass/TestStudent1.java

import javax.swing.*;

public class TestStudent1 { public static void main(String[] args) { Student1 tatiana; Student1 pupil; //... Create new Student1 object with new. tatiana = new Student1(); tatiana.firstName = "Tatiana"; tatiana.lastName = "Johnson"; tatiana.id = 9950842; //... Create another Student1 object. pupil = new Student1(); pupil.firstName = JOptionPane.showInputDialog(null, "First name"); pupil.lastName = JOptionPane.showInputDialog(null, "Last name"); pupil.id = Integer.parseInt(JOptionPane.showInputDialog(null, "ID")); JOptionPane.showMessageDialog(null, "One student is named: " + tatiana.lastName + ", " + tatiana.firstName + "\n and another is named: " + pupil.lastName + ", " + pupil.firstName); } }

OOP 3. Constructor - Student Class


Purpose of this lesson:

To introduce the concept of constructors. Purpose of constructors is both guaranteed initialization and convenience.

New Java language features

Constructor syntax - like a method but with class name and implicit type/value.

Add a constructor for better initialization


Avoid bad initializations. One problem with the Student1 class is that the user has to explicitly initialize all fields. This requires extra typing, but more importantly, it is error-prone. If we forget to initialize a field, the default value could have bad consequences. Convenience. Defining a constructor makes creation of an object easier to write.

Constructor Syntax
Similar to method. A constructor is similar to a method -- it's called like a method, has parameters like a method, and it returns. But it must have the same name as the class for which it is a constructor. Also, the type and return value are implicit.

Student2 example with a constructor


Here is the Student1 class with a constructor which simply initializes the fields (instance variables) from its parameters. Often constructors do more work in initialization, including checking for legal values, but for now we'll just simply copy the parameter values.

// File

: oop/dataclass/Student2.java

// Purpose: Information about a student. Defines constructor. public class Student2 { public String firstName; // First name public String lastName; public int id; // Last name // Student id

//======================================== constructor public Student2(String fn, String ln, int idnum) { firstName = fn; lastName id } }
Note that a constructor has no return type and the name is the same as the class name. Using the constructor Here is the first program rewritten to use the above class definition with a constructor.

= ln; = idnum;

// File : oop/dataclass/TestStudent2.java // Purpose: Tests Student2 constructor. import javax.swing.*; public class TestStudent2 { public static void main(String[] args) { Student2 tatiana; Student2 pupil; //... Create new Student2 object with new. tatiana = new Student2("Tatiana", "Johnson", 9950842); //... Create another Student2 object. String first = JOptionPane.showInputDialog(null, "First name"); String last = JOptionPane.showInputDialog(null, "Last name"); int studID= Integer.parseInt(JOptionPane.showInputDialog(null, "ID")); pupil = new Student2(first, last, studID); JOptionPane.showMessageDialog(null, "One student is named: " + tatiana.lastName + ", " + tatiana.firstName

+ "\n and another is named: " + pupil.lastName + ", " + pupil.firstName); } }


When you define a constructor, the Java compiler doesn't create a default constructor if you define a constructor in a class, the Java compiler no longer automatically creates a default (parameterless) constructor. All object creation therefore must use your explicitly defined constructor. For example,

Student2 someone; someone = new Student2(); constructor. // ILLEGAL. There is no default // OK. Must specify 3

someone = new Student2("Michael", "Maus", 1); values.

The constructor can check that all fields are defined with legal values. We're not going to extend the Student2 class any further to test for legal values, but we will in the next example. For the moment we'll leave the Student class, and move to something different to show the same ideas.

OOP 4. Data+Constructor - TimeOfDay


Purpose of this lesson:

Show another example of a class with constructor.

TimeOfDay1 Example - No constructor


Let's say that we want to represent a time of day necessary for representing when an appointment is scheduled. It won't represent the day, only the time as hour and minute. Here's a start using a 24 hour clock (00:00 to 23:59). TimeOfDay1.java

// File : // Purpose: 2 // // Author : 3 1

oop/timeofday/TimeOfDay1.java A 24 hour time-of-day class. This simple value class has public fields. Fred Swartz - 2005-05-30 - Placed in public domain.

4 public class TimeOfDay1 { public int hour; 5 public int minute; 6} 7 8 9


Test program

// File : // Purpose: 2 // // Author : 1

oop/timeofday/TimeTest1.java Test the TimeOfDay1 class. Shows use of dot notation to select public fields. Fred Swartz, 2005-05-04, Placed in public domain.

3 import javax.swing.*; 4 5 6 7 8 9 10 11 12 13 } 14 15 16 17 18 19 20 21 } public class TimeTest1 { public static void main(String[] args) { //... Create a new TimeOfDay object. TimeOfDay1 now = new TimeOfDay1(); //... Set the fields. now.hour = 10; // Set fields explicitly. now.minute = 32; //... Display the time by referencing the fields explicitly. JOptionPane.showMessageDialog(null, now.hour + ":" + now.minute);

TimeOfDay1b.java - As above, but with constructor


1 2 3 4 5 6 7 8 // File : // Purpose: // // // // Author : oop/timeofday/TimeOfDay1b.java A time-of-day class with constructor, which provides a more convenient and conventional way to build objects. The constructor is overloaded (more than one version) for more convenience. Fred Swartz, 2007-02-27, Placed in public domain.

public class TimeOfDay1b { public int hour; public int minute; //==================================================== constructor //Note 1 public TimeOfDay1b(int h, int m) { hour = h; // Set the fields from the parameters. minute = m; } }

9 10 11 12 13 14 15 16 17
Notes 1. Constructors have no return type, and have the same name as the class.

Test program using constructor

// File : oop/timeofday/TimeTest1b.java // Purpose: Test the TimeOfDay1b class. // Author : Fred Swartz, 2007-02-27, Placed in public domain. import javax.swing.*; public class TimeTest1b { public static void main(String[] args) { //... Create a TimeOfDay1b object for 10:30 in the morning. TimeOfDay1b now = new TimeOfDay1b(10,30); //... Display it. JOptionPane.showMessageDialog(null, now.hour + ":" + now.minute); } }

OOP 5. Constructor Overloading - TimeOfDay


Purpose of this lesson:

Introduce constructor overloading -- multiple constructors differing in number or types of parameters. Typically this is used to provide optional initialization parameters.

New Java language features:

Use of "this(...)" to call one constructor from another. The "this(...)" call must be first line a constructor.

Good Practice:

Using "this(...)" is much better than duplicating code.

Overloading constructors
It's common to overload constructors - define multiple constructors which differ in number and/or types of parameters. For example, exact hours are common, so an additional constructor could be defined which takes only the hour parameter. You can then set to minutes to a default value.

// File : // Purpose: 2 // // 3 // 4 // Author : 1

oop/timeofday/TimeOfDay1c.java A time-of-day class with constructor, which provides a more convenient and conventional way to build objects. The constructor is overloaded (more than one version) for more convenience. Fred Swartz, 2005-05-04, Placed in public domain.

5 public class TimeOfDay1c { public int hour; 6 public int minute; 7 //==================================================== constructor 8 public TimeOfDay1c(int h, int m) { 9 hour = h; minute = m; 10 } 11 //==================================================== constructor 12 public TimeOfDay1c(int h) { 13 hour = h; minute = 0; // Set minutes to 0. 14 } 15 } 16 17 18 19 20 21 22 23

Calling one constructor from another using "this(...)"


Default parameters. It's very common for a constructor with fewer parameters to call a constructor with more parameters, supplying default values. For this usage, the constructors with fewer parameters will frequently consist of only the "this" call. "this". Instead of calling the constructor with the class name, use the keyword constructor with the appropriate number and types of parameters, and calls it. Must be first. The "this" call must be the very first line of the constructor.

this. The compiler matches "this" with a

// File : // Purpose: // // Author :

oop/timeofday/TimeOfDay1d.java A time-of-day class with overloaded constructors. One constructor calls the other using "this". Fred Swartz, 2007-02-27, Placed in public domain.

public class TimeOfDay1d { public int hour; public int minute; //==================================================== constructor public TimeOfDay1d(int h, int m) { hour = h; minute = m; } //==================================================== constructor public TimeOfDay1d(int h) { this(h, 0); // Call other constructor. } }

Hidden constructor call at the beginning of every constructor


The one essential way in which constructors differ from methods is that the first statement of every constructor is either a call on the constructor for the superclass (using super) or a call to another constructor in the same class (using this). Hidden call. You normally don't see the super call because the compiler automatically generates a call to the parameterless superclass constructor for you, but it's generated at the beginning of every constructor which doesn't explicitly call another constructor.

public TimeOfDay1d(int h, int m) { hour = h; minute = m; }


Is the same as.

public TimeOfDay1d(int h, int m) { super(); // Call Object constructor. hour = h; minute = m;

"Copy" Constructors
Another reason to overload constructors is to provide a copy constructor, which builds an object from the values of another object of the same class. [Note: Another way to do this is to implement the clone() method.]

// File : // Purpose: // // Author :

oop/timeofday/TimeOfDay1d.java A time-of-day class with overloaded constructors. Implements a copy constructor. Fred Swartz, 2007-02-27, Placed in public domain.

public class TimeOfDay1e { public int hour; public int minute; //==================================================== constructor public TimeOfDay1e(int h, int m) { hour = h; minute = m; } //==================================================== constructor public TimeOfDay1e(int h) { this(h, 0); // Call other constructor. } //==================================================== constructor public TimeOfDay1e(TimeOfDay1e other) { this(other.hour, other.minute); // Call other constructor. } }

Questions
1. What would happen if you called the following constructor?

TimeOfDay1e dentistAppointment = new TimeOfDay1e();

OOP 6. Validity Checking - TimeOfDay


Purpose of this lesson:

Show how constructor can guarantee legal initial values.

New Java language features

Throwing an IllegalArgumentException.

A constructor can ensure good values


By defining a constructor, all TimeOfDay objects must be created with your constructor. This gives you control over how parameters are used, and most importantly it can prevent the creation of illegal TimeOfDay values. What to do if there are errors. Errors can be grouped into two general classes:

User errors. If the user makes an error, the user interface code must tell them what they did wrong, how to correct it, etc. This is an issue for the user interface code, not for your basic value objects. Either the user interface should check for values before passing them to the model code, or the model code should have some way of informing the user interface that there was an error, typically by throwing an exception. Programmer errors. You should be very unforgiving of programmer errors discovered during testing There are several ways to handle errors (see Error processing). One of the best ways to handle bad values is to throw an exception (see Throwing exceptions) to stop execution if an illegal situation is encountered.

Crash please. The TimeOfDay class is called by a programmer, not the user. If illegal values are passed to the constructor, it's because the programmer isn't doing their job, so the program should be stopped immediately. The program below should crash because an illegal number of minutes is passed to the second call on the constructor. The result would be an error message something like the following.

Exception in thread "main" java.lang.IllegalArgumentException: TimeOfDay: Bad constructor value: 14:99 at TimeOfDay2a.<init>(TimeOfDay2a.java:16) at TimeTest2a.main(TimeTest2a.java:27)
TimeOfDay class

// // // // //

File : Purpose: Author : Date : Issues :

oop/timeofday/TimeOfDay2a.java A 24 hour time-of-day class to demo intro OOP concepts. Fred Swartz 2009-09-18 Validity checking.

public class TimeOfDay2a { //========================================= instance variables public int hour; public int minute; //================================================ constructor public TimeOfDay2a(int h, int m) { //... Check values for validity. if (h < 0 || h > 23 || m < 0 || m > 59) { throw new IllegalArgumentException( "TimeOfDay: Bad constructor value: " + h + ":" + m); } hour = h; minute = m; } }
Test program source The following program will produce a dialog box indicating that an exception was correctly thrown, then it will produce an error on the console (if run from the console) because the exception was not caught.

// File : oop/timeofday/TimeTest2a.java // Purpose: Test TimeOfDay2a exception throwing.. // Author : Fred Swartz - 2006-09-18 - Placed in public domain.

// Issues : When you run this test, it should produce an error. import javax.swing.*; public class TimeTest2a { public static void main(String[] args) { //... First constructor call is OK try { TimeOfDay2a now = new TimeOfDay2a(8 , 35); // OK } catch (IllegalArgumentException iax) { JOptionPane.showMessageDialog(null, "Failure: " + iax); } //... Constructor should fail. try { TimeOfDay2a never = new TimeOfDay2a(14, 88); // ILLEGAL VALUE. } catch (IllegalArgumentException iax) { JOptionPane.showMessageDialog(null, "Success: " + iax); } //... Exception gets passed up to runtime environment to console. TimeOfDay2a never = new TimeOfDay2a(14, 99); // ILLEGAL VALUE. } }

OOP 7. Private data - TimeOfDay


Purpose of this lesson:

Make data private for reliability. Write getters and setters to work with private data. Instance methods can use the instance variables (fields).

New Java language features

private keyword.
Methods defined without the

static keyword are instance methods.

Naming conventions for fields.

Good Practices

Only define getters for values that people need to know about. Setters are often not defined so that immutable objects can be created.

Bulletproofing with private, getters, and setters

To make reliable software, it's essential to protect the data in an object - insure that it is initialized, and prevent illegal or inconsistent values. The key to this is to declare the fields private. Private data reduces complexity by preventing unintended coupling -- references to fields inside your class from other classes.

Bad Practice - Excessive Coupling


Risk. Public fields put the integrity of objects at great risk. Nothing prevents the following bad statements from being executed if the fields are public.

TimeOfDay3 goodTime = new TimeOfDay2a(11, 11); goodTime.minute = 99;

// Legal values.

// AVOIDS CONSTRUCTOR VALIDITY CHECK

But who would do that? Of course no programmer would intentionally set the value to something illegal like this, but there could be several reasons to mistakenly set it. Here are two examples.

goodTime.minute = userValue; goodTime.minute++;

// FAILED TO CHECK INPUT VALUE FIRST. // WHAT HAPPENS AFTER 59?

Solution - Private fields, public methods to get/set them


Private data. The key to making classes safer and easier to change is to declare fields

private. Constructors and

methods in the same class can use the field variables, but no one outside the class can see them. However, if they're private, something must be done to allow getting and setting the values. This is done with so calledgetter and setter methods.

Getters and Setters


Naming. If it's appropriate for the user of a class to get or set field values, the convention is to write public getter and setter methods. The Java convention is to begin such method name with "get" or "set" followed by theattribute that should be obtained or set. Final parameters. A good case can be made for declaring setter parameters constructor and setter parameters. Getters and setters can be evil. Don't automatically write getter and setter methods for every private instance variable.

final. See Code Advice #12: Use final on

They can make your code inflexibly dependent on a particular implementation. There is often no need for others to know about every internal field. Don't write both a getter and setter if both are not appropriate. Getter and setter methods do not even need to correspond to specific fields -- they provide a user interface to your class, but internally you are free to make changes. We'll make such a change to the TimeOfDay class shortly.

It seems awkward to write these, and some languages and IDEs have made this either automatic or easier to do. There is controversy about how easy it should be go create getters and setters, because they shouldn't exist for all instance variables.

Alternative to getters/setters

A principle of OOP is that you should ask an object to perform a service for you, not just give you data. If your class is a simple "value" class -- a class which just represents a simple value, it may be appropriate to have getters and setters. As a class becomes more complex, it's often more appropriate to supply methods which do the necessary computation rather than letting the user get the values and do the computation themselves.

Instance, not static, methods


Getter and setter methods are instance, not static, methods. Instance methods can reference instance variables, but static methods can not. Instance variables can only be referenced if there is an object (instance) that holds them, of course.

A note about field names - a _convention


When you read long methods it isn't always obvious whether a variable is a parameter, local variable, field (instance variable), or class (static) variable. Because instance variables have such a distinct meaning, many programmers find it useful to prefix field names with something special. Variations on the instance variable name "hour" _hour Common, although it violates some Java style conventions. I use it frequently.

myHour hour m_hour mHour fHour

Less common, but you will see it sometimes. Instance variable looks like other variables. Common, but unhelpful. A C++ convention for "member" variables. Common in Java too. Another common convention originating in C++. The "f" denotes "field" variable.

Controversial. Like brace conventions, field prefixes are controversial. I highly recommend naming instance variables differently than local variables, but when you collaborate with others on a project there will often be a naming convention which you must use, or your instructor may insist on one style. Therefore be flexible on this topic. Naming other kinds of variables. Some programmers use naming conventions for parameters (eg, start parameter names with "p") or class (static) variables (eg, start names with "c"). Because parameters are essentially local variables which occur in only a limited span of code, there isn't as much interest in distinguishing them. However, class variables are seriously different, and it's good practice to name them differently. Because they're relatively rare, there hasn't been as much controversy or consensus on naming conventions.

TimeOfDay3
Here's the TimeOfDay class, rewritten with private instance variables and getters and setters.

// File : oop/timeofday/TimeOfDay3.java // Purpose: A 24 hour time-of-day class to demo intro OOP concepts. 2 // Author : Fred Swartz - 2006-09-18 - Placed in the public domain. // Issues : Makes variables private, adds getters and setters. 3 // Can be improved by calling setters from constructor. 4 public class TimeOfDay3 { 5 //========================================= instance variables private int _hour; 6 private int _minute; 7 //================================================ constructor 8 public TimeOfDay3(int h, int m) { 9 //... Check values for validity. if (h < 0 || h > 23 || m < 0 || m > 59) { 10 throw new IllegalArgumentException( 1

11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 } }

"TimeOfDay: Bad constructor value: " + h + ":" + m); } _hour = h; _minute = m; //================================================== getHour public int getHour() { return _hour; } //================================================== setHour public void setHour(int h) { if (h < 0 || h > 23) { throw new IllegalArgumentException( "TimeOfDay setHour: Bad hour value: " + h); } _hour = h; } //================================================ getMinute public int getMinute() { return _minute; } //================================================ setMinute public void setMinute(int m) { if (m < 0 || m > 59) { throw new IllegalArgumentException( "TimeOfDay setMinute: Bad minute value: " + m); } _minute = m; }

48 49 50
See one of the problems below for a way to improve this class. Test program

// File : oop/timeofday/TimeTest3.java // Purpose: Test the TimeOfDay3 class.. // Author : Fred Swartz - 2006-09-18 - Placed in public domain. import javax.swing.*; public class TimeTest3 { public static void main(String[] args) { TimeOfDay3 then = new TimeOfDay3(8, 35); TimeOfDay3 now = new TimeOfDay3(14, 5); //... Print the hours and minutes of the times. JOptionPane.showMessageDialog(null, "From " + then.getHour() + ":" + then.getMinute() + " to " + now.getHour() + ":" + now.getMinute()); // THE FOLLOWING WOULD BE ILLEGAL // now._Hour = 99; // Can't reference private field. } }

Terminology note
Java uses the terms getter and setter, but you may also see the C++ terms accessor and mutator.

Programming exercises
1. Improvement. This class definition above is OK, but it could be improved by calling the setter methods from the constructor so that code isn't repeated. This code violates the DRY (Don't Repeat Yourself) principle. Rewrite the constructor with this improvement. Make the Student class (see 3. Student - Constructor) robust with private instance variables, getters and setters, and checks for legal values (eg, name strings must not be null or the empty string and the idmust be in a certain range).

2.

OOP 8. Visibility and Coupling


Purpose of this lesson:

Reduce visibility to reduce coupling.

New Java language features

The visibility options: package,

public, private, protected.

Good Practices

Declare fields private, except for very simple value classes. Exceptions should be rare. Most methods will not be private.

Reduce coupling
To achieve the best encapsulation (information hiding) you should always declare methods with the least visibility that works. In small programs there's really no problem, but in large programs this problem of excessivecoupling is very serious. Coupling occurs when one part depends on the specific implementation of another. The more coupling there is the more costly it becomes to make changes because too much code depends on specific implementations. This causes software rot - a program becomes progressively less usable because it can't be easily upgraded.

Visibility

public

private

, or package

private - This should always be your first choice for instance variables. It is rare for an instance variable to have any permission except private. All instance methods in the same class can use a private instance
variable, but no methods in other classes can even see it. Communication between classes should be by means of methods, not variables, so methods will normally not be private. default (package) - If you don't specify anything, the default visibility allows classes in the same package (directory) to see it. This is a good, and common, choice for classes and methods, but should not be used for instance variables, which should be private.

public - Let's anyone see it. Choose this if you've defined a method that will be used by others outside of your project. Note that main is the only method that must be declared public so the run-time system can see it
and call it.

protected - Only use this after careful thought. See optional discussion below.

protected

and why you might avoid it (Optional)


protected visibility should be used. It is like private, but

There is substantial controversy about whether additionally grants visibility to child classes.

One problem is that anyone can make a child class which can reference it. If someone has access to your class, they can make this variable or method effectively public by supplying a getter and setter for it. There is protection against casual access, but not against anyone who feels a real need to access private data/methods. Perhaps its main use is in making anyone who is thinking about using protected variables/methods think a little more about it. Protected access also encourages coupling between the parent and child class, as with all inheritance. This coupling can prevent improvements or changes to the parent class, and should be discouraged. Using protected access is only useful if you've designed your class so that others can extend it. Designing for inheritance is not trivial because you have to imagine all the ways it might be used. I believe Elliotte Rusty Harold (Java book author) offered the opinion that designing for inheritance takes about three times as much work as not allowing inheritance! For example, if the user wanted to use it in a Map, you did override hashcode(), didn't you? Of course, if it's for your own use, you'll be able to fix things easily.

OOP 9. toString() - TimeOfDay

Purpose of this lesson:

Show common implementation of

toString() method.

The

toString

instance method
toString, which returns a string representation of an object. This is convenient for

A common method to write is

displaying the value of an object for either debugging or for console IO. String concatenation of objects. If you try to convert an arbitrary object to a String, as when you concatenate anything with a String, Java calls the object's toString method. If you didn't define this method, then your class inherited toString from the Object class. Object's version of toString doesn't produce anything very useful -- it gives the name of the class and the hexadecimal location in memory, for example, "TimeOfDay@82ba41".

TimeOfDay2 with
// // // // File : Purpose: Author : Issues :

toString

method
toString method has been defined.

This class is the same as in the previous example, except that the

oop/timeofday/TimeOfDay2.java A 24 hour time-of-day class to demo intro OOP concepts. Fred Swartz - 2006-09-18 - Placed in public domain. Add a toString() method.

public class TimeOfDay2 { //========================================= instance variables private int _hour; private int _minute; //================================================ constructor public TimeOfDay2(int h, int m) { setHour(h); setMinute(m); } //================================================== getHour public int getHour() { return _hour; } //================================================== setHour public void setHour(int h) { if (h < 0 || h > 23) { throw new IllegalArgumentException( "TimeOfDay setHour: Bad hour value: " + h); } _hour = h; } //================================================ getMinute public int getMinute() { return _minute; } //================================================ setMinute

public void setMinute(int m) { if (m < 0 || m > 23) { throw new IllegalArgumentException( "TimeOfDay setMinute: Bad minute value: " + m); } _minute = m; } //================================================= toString @Override public String toString() { return _hour + ":" + _minute; } }
Test program using

toString

Note how convenient the output is.

// // // // //

File : oop/timeofday/TimeTest2.java Purpose: Test the TimeOfDay2 class. toString called automatically for concatenation. Author : Fred Swartz Date : 2005-04-30

import javax.swing.*; public class TimeTest2 { public static void main(String[] args) { TimeOfDay2 then = new TimeOfDay2(8, 35); TimeOfDay2 now = new TimeOfDay2(14, 5); JOptionPane.showMessageDialog(null, "From " + then + " to " + now); } }

Exercises
1.

Two digit times We normally expect to see time values expressed with two digits, but the version oftoString above formats numbers less than 10 as single digits, eg 12:7 although we would expect to see12:07. Change toString to do this. Although a good way to do this would be to use DecimalFormat or the newer String.format to accomplish this, try it using only if statements and
string operations for practice. toString12(). Write a method,

2.

toString12, that returns the time as a string in 12-hour form,

appending AM or PM as appropriate. For example, for the time 22:37 would be returned as "10:37 AM". There are three cases: o Before 12 is AM. o Between 12 and 13 is PM, but written with 12. o 13 and after are PM with 12 subtracted from the hour.

You might also like