Methods become much more useful when they can receive information from the calling method, do some operations on them, and then pass a computed value back for the calling method to do with as it pleases.
extensionCore Concept 1: Summary of three method structures
Methods are named blocks of code that perform a single function in a program. They are valuable since they help us eliminate duplicate code, isolate logic for testing, and allow for modular code development.
The following annotated screen capture shows the three essential elements of the method system in Java:
The method's declaration (often called its signature)
The method's body that carries out program tasks
A call to this method from some other method (or from within itself!)
Figure 1: A method's declaration, body, and call
The red numbered lines in the left margin show the flow of execution from the method call in main to displayPattern, and then back down to main. Remember, methods can be stacked in any order: main can live wherever we want in our classes.
We can categorize methods into three types summarized in the feature box below. Chunk 1, Module 1 explored types I: Simple, no-argument methods and type II methods: those which require an input value but return nothing. This module introduces type III methods.
type I methods
The simplest of all possible methods: a named block of code that "just does its thing" when called, requiring no inputs and returning no values.
Type I method declaration and body
Type I method call
Type I method output
type II methods
These methods require one or more pieces of data to carry out its task. We specify what the method requires in its declaration. When we pass this data into the method during execution, we specify the values to send with arguments to these methods.
Type II method declaration and body
Type II call with input parameter
Type II output
type III methods
"Fully-baked" methods which take in one or more values and return a computed value of a declared type. A good chunk of all methods we use in Java are type III methods since receiving values from a method is a very useful process.
find_in_pageIntroduction to the GeometricShapes calculator example program
Coding to a specification
Most professional coding projects you may join will likely be well underway by the time you arrive on the scene. Dozens if not hundreds of Java Classes will have been written which already carry out business processes.
In order for the code you write to be useful it must work seamlessly with existing code. By "work" we mean compute the desired values in the desired form when called with the specified information.
Specifications in action
For example, if your organization is building an event registration system and you are tasked with creating e-tickets in Java, you will be writing classes that contain methods such as refundTicket. This method will need to receive information about which ticket to refund and carry out the necessary actions to issue the refund.
In order for this project to work, your team leader will have likely written up a specification document like the ones in the light green boxes in this module. You'll then be tasked with converting that specification into working Java code.
Let's practice coding to specification
The following core concepts and exercises will involve creating code that meets the following program specification. It is based on a business tool creation model in which a technology team at the organization creates programs to assist employees to carry out their jobs.
Study the following specification, figures, and explanations so you understand why we are studying the methods and code in the next few sections.
Create a geometric shape calculation tool to assist packaging specialists at a mom-and-pop-brick-and-mortar-online-retailer in Pittsburgh.
The tool will operate through a command line-based interface loaded onto a computer sitting in the packaging area. For each of three geometric shapes, the user can enter the dimensions of each. The program should print out the computed area or volume measurement
required code structure
The program should exhibit method-based coding to isolate the math involved in each shape's area or volume calculation. The user's input for these tools and the printing out of results should all happen in the program's main method--not in the shape measurement calculation methods.
Each method should take input parameters corresponding with the necessary figures for computing the desired area or volume calculation (side length, width, etc.).
Each method should return a single value corresponding to the computed area or volume calculation. There should be no calls to System.out.println() in any of the computing methods.
Sample program output
This program output meets the above specification. The following sections will develop and digest the code to generate this output. A link to the source posted on GitHub is located at the end of Exercise 2
Program class diagram sketch
Before we sit down to write code, we should envision the high level structure of the class we are about to create. Ask ourselves the following:
What descriptive name should I give the class? OR What is the specified name for this class?
Which methods will I need to create in order to isolate each core program task in it's own named block of code?
Where will each of my methods get called? What information needs to get transferred to those methods?
Using the above questions as a guide, a sketch of the class structure might be created as follows. Note that the complete method signatures and information flow requirements have not yet been fleshed out. We're looking at the most abstract view of the class's design.
extensionCore Concept 2: Writing Type III methods which take input parameters and return values
In this core concept section, we'll be creating methods that all compute some sort of geometric value based on the inputted values. The first method we'll write calculates the volume of a cube when passed in the length of any given side. We can model the method like this:
Setting up our GometricShapes class
Create a skeleton of our class which we'll add meat to during this module. Use these steps:
Create a new package called week8_methods2
Inside this package, create a class called GeometricShapes
Code up a main method with the proper method signature
Skeleton of GeometricShapes class with one method
Once we have the skeleton designed, most of our planning-based work is done. The key decisions are how we wrote the declaration to our method: each keyword on the declaration line specifies an aspect of the method's behavior. Let's look at each component up close:
Coding up calcVolumeOfCube
We can start coding now that we have the structure and objective in our heads. The guts of calculateVolumeOfCube involve one line of computational code which raises the passed in value to the third power. The result of that computation (which itself is a method call) is stored in a local variable called cubeVolume.
Listing 1: code for calcVolumeOfCube
Note the use of the Java keyword return inside this method. This keyword instructs the Java virtual machine to do two things:
Evaluate the expression to the right of the keyword return and pass the result back to the calling method.
Transfer execution of the program from that very line to the calling method
java type checking
Note that the use of a return statement is a prime example of Java's type checking system. Like in all variable manipulation in Java, the type of the value of the return expression must match the type specified in the method signature. In our case, a variable named cubeVolume makes up the entire expression. All is well with the type checking system since cubeVolume is declared to be type double.
Error messages are our friends!
Tinker with your code and try changing the type of the expression you place after return. In the error case above, when we try to send a String literal back to the caller, the pre-compiler flags this and tells us that String is not (and cannot be converted to) a double value, which the method specification requires.
We now have the declaration and guts of our calcVolumeOfCube method, and are now ready to use that method to carry out its computation. We are in step three of our method design process:
Call method with an input parameter and structure to hold the return value
We've called methods with input parameters before, but have not been explicit about the structure for calling methods which not only require an input value but give us a value in return. Study the following call to calcVolumeOfCube from inside our main method. Note how we store its return value in a new local variable called result which we then send to System.out.println() to be displayed on the terminal window..
Type III call with input parameter and a variable to store the returned value
The output shows that we successfully passed 50.0 into calcVolumeOfCube and retrieved the returned volume computation for display to the user.
Type III method & call output
Many options for handling returned values
The above code does the simplest possible action with the returned double value from calcVolumeOfCube: it simply dumps the value into a local variable called result and turns right around and displays that to the user. Since result is only used for two lines, we could have compacted our code by calling calcVolumeOfCube inside our call to System.out.println(). It's a nested method call!
motorcycleExercise 0: Adding user input to our GeometricShapes program
With our structure setup for calling and receiving values from calcVolumeOfCube, let's replace our hard-coded value of 50.0 with a local variable of your design which the user can populate through the console. Code to the following specification:
exercise 0 program specification
Adjust (refactor) your code in main to prompt the user for the cube's side length. Store whatever the user enters in a local variable. Pass that local variable into calcVolumeOfCube instead of the current hard-coded value.
Capture the returned volume computation. Adjust the display to the user to include a printout of the value they entered along with the computed value.
Study the following program output that meets this specification:
Check your work
This button reveals a possible implementation of the specified program above. Note that we call the nextDouble() method on our Scanner object to retrieve a double from the user. We must use nextDouble() instead of nextInt() since our method calcVolumeOfCube requires a number of type double.
motorcycleExercise 1: Adding a cylinder volume calculation method
Pull together our explorations with calcVolumeOfCube to write and call a third method inside the GeometricShapes class called calcVolumeOfCylinder. Remember: this is our workflow for creating and calling methods:
Methods can take many input parameters
A method can require zero, one, or more than one input parameters. Each parameter must be specified in the method's declaration and (inside its parentheses). If more than one method parameter is specified, each must be separated by commas and preceded by its type. Here's a silly example to illustrate this point:
Call the method with the required parameters in ORDER
When we call manyParams, we must pass in all four required parameters, in the order given in the method's declaration. Here's a sample call that passes in data literals instead of variable values (which would be much more typical).
Don't forget about the math
We can calculate the volume of a cylinder with the following formula. Note that this computation requires two values: the radius of the cylinder's circular ends and the height of the "tube". This will translate into two input parameters in our method.
Since calculating the volume of a three dimensional cylinder requires both the radius and the height, the method you'll program in this exercise will require two input parameters (not four :))
Study the following specification and jump on the keyboard!
exercise 1 program specification
Design a method called calcVolumeOfCylinder which takes in two input parameters, both of type double, which represent the radius and the height of the cylinder.
Since we're still getting into the swing of programming methods, you can reference the following code snippet that could become part of the guts of your calcVolumeOfCylinder method.
Note that this line of code does not complete the method's guts: we still need to return the volume of the cylinder to the calling method with a return statement.
Call calcVolumeOfCylinder from main. Just like we did for the cube, gather a height and base radius from the user which you'll then pass down to calculateVolumeOfCylinder() which it will use to compute the volume and return it to the caller
This is the output of a program that meets these specifications
motorcycleExercise 2: Adding your favorite shape computation method
Choose an interesting shape
With our methods to calculate the volume of a cube and a cylinder in place, you've got the skills necessary to add your own shape computation to GeometricShapes!
Use references resources of your choosing (or your brain only!) to find a cool shape that might store materials that need to be shipped (remember, the program is for shipping specialists). Here are some ideas of varying difficulty:
Check out wikipedia's extensive article on four-sided shapes and choose one and a formula to computing its area or volume. Choose a shape that's meaningful to you. Perhaps obtuse triangles bring back fond childhood memories, or parallelograms whisk you back to a relaxing vacation.
Now that you have a chosen shape and a computation related to that shape, grab a pen and paper and work out a few sample problems. Note how many different measurements you need to complete the computation: each of these will become an input parameter to your method.
Follow our familiar steps:
Use exercise 1's specification as a model: except replace cylinder with your chosen shape. When done, test your method against a known solution. Finally, make sure you have a nicely formatted user interface so the measurements needed are clearly explained.
This project asks that you assemble your learning from the above core concepts and exercises into a working program structured with method calls and proper flow of data to and from those methods.
As usual, we should always try to code to a specification--even if that specification is one we make for ourselves. We must organize our logic around some specific goal, and revise that goal if necessary.
Create a handy unit conversion program which can transform unit quantities entered by the user into a chosen unit type (e.g. knots into miles per hour).
Choose three pairs of units that you might actually want to convert between in your life or work. They can be related to a single type of measurement (speed, volume, weight, etc.) or be drawn from several types of measurement.
Accurately compute the conversions by hand using correct formulas. The conversion references linked below might be handy. The inter-webs can supply many others.
Mushy Brain Warning: You are learning to program Java, so do the thinking yourself: do not conduct an Internet search for something like "convert miles to km in java". Stick with "convert miles to km" and figure the Java out for yourself.
Create an appropriately named class composed of a main method which coordinates the flow of data to and from methods which implement data cleaning and conversion operations.
Create a separate method for each of your three conversions. Name your methods with action words (e.g. convertMilesToKm).
Plan your method signatures carefully. Each method should require one or more input parameters and return the final converted value to the caller. Once your methods are in place with proper signatures, you're well on your way.
In the main method, create a very simple user interface which prompts the user for values to convert and displays the converted values. Be sure to tell the user the unit of measurement to enter, and what will be computed.
The unit conversion algorithm writing and method calling is a substantial project by itself, so your user interface can be bare bones. It would be handy to program a switch statement inside a while loop to allow the user to choose a converter to execute, but this is not necessary for this exercise.
The program generating this output meets the above specifications. Remember! You can always add features above requirements in this class, so don't limit yourself by sample output.
Suggestions & tips
If you are struggling with how to implement a conversion factor into a Java method, you can peek at this yards-to-miles converter. Remember, use this as a model: choose three of your own conversions to build.
Plan your program before you jump into the nitty gritty of programming your method guts. Write a main method and your three conversion method declarations first. Think them over. Then write the code for each method one at a time, testing as you go.
Try to generate conversion methods for units that you would actually find useful to convert between. Think about your work, hobbies, daily life, cooking, etc.
Build a nice user interface that allows the user to choose which unit converter method to employ. A switch statement will come in handy here.
Choose a set of three unit conversion pairs that can be chained together. When the user enters a single value, the first method in the chain is called, and output received. When that output returns to main, immediately pass it to another method as that method's input. For example, you might have conversion methods between hours of running the furnace and cubic feet of gas. Then a second method converts cubic feet of gas into something interesting, like volume of extraction-related waste water generated. The output can then show the user each amount as the program executes down the chain. Include links to sources used in your program's comments!
Do some internet sleuthing and learn how to "trim" double values so your output after some non-integer conversions doesn't show twenty million digits of precision. Include links to sources--and don't copy and paste Java code! Read the example code and write your own, without copying!