Blakes 21 Days Chapter 5 Document
- Internal Links
- Chapter 5 pages 125 to 156 | 156 - 125 = 31 pages | reserve
Day 5, Creating Classes and Methods
- Top
- 125 If you're coming to Java from another programming language, you might be struggling with the meaning of the term class.
- It seems synonymous with the term program, but you might be uncertain of the relationship between the two.
- 125 In Java, a program is made up of a main class and any other classes needed to support the main class.
- These support classes include any you might need in the Java Class Library, such as String, Math and the like.
- 125 Today, the meaning of class is clarified as you create classes and methods, which define the behavior of an object or class.
- You learn about each of the following:
- The parts of a class
- The creation and use of instance variables
- The creation and use of methods
- The use of the main() method in applications
- The creation of overloaded methods
- The creation of constructors
Defining Classes
- Top
- 126 Because you have created classes during each of the previous days, you should be familiar with the basics of their creation at this point.
- A class is defined via the class keyword and the name of the class, as in the example:
class Ticker {
// body of the class
}
- By default, classes inherit from the object class, the superclass of all classes in the Java class hierarchy.
- The extends keyword is used to indicate the superclass of a class, as in this example, which is defined as a subclass of Ticker:
class SportsTicker extends Ticker {
// body of the class
}
- A class that does not use extends to identify its superclass, has Object as its superclass.
Creating Instance and Class Variables
- Top
- 126 Whenever you create a class, one thing you must do is define behaviour that makes the new class different from its superclass.
- This behaviour is defined by specifying the variables and methods of the new class.
- In this section, you work with three kinds of variables:
- instance variables,
- local variables,
- and class variables.
- The subsequent section covers methods.
Defining Instance Variables
- Top
- 126 On Day 2, "The ABC's of Programming," you learned how to declare and initialize local variables, which are variables inside method definitions.
- Chap 2: Variables and Data Types (defines the three kinds of variables)
- Instance variables are declared and defined in almost the same manner as local variables.
- The main difference is their location in the class definition.
- Variables are considered instance variables
- if they are declared outside a method definition
- and are not modified by the static keyword.
- Chap 1: About the Java code ... (link to static)
- By programming custom, most instance variables are defined right after the first line of the class definition, but they could just as easily be defined at the end.
- Top
- 127 Here's a simple class definition for the class MarsRobot, which inherits from the superclass ScienceRobot:
class MarsRobot extends ScienceRobot {
String status;
int speed;
float temperature;
int power;
}
- This class definition contains four variables.
- Because these variables are not defined inside a method, they are instance variables.
- The variables are as follows:
- status - A string indicating the robot's current activity, for example, "exploring" or "returning home".
- speed - An integer that indicates the robot's current rate of travel
- temperature - A floating-point number that indicates the current temperature of the robot's environment
- power - An integer indicating the robot's current battery power
Class Variables
- Top
- 127 As you learned in previous days, class variables apply to a class as a whole, rather than to a particular object of that class.
- Chap 3: Class Variables
- Class variables are good for sharing information between different objects of the same class or for keeping track of common information among a set of objects.
- The static keyword is used in the class declaration to declare a class variable, as in the following example
- static int SUM;
static final int MAX_OBJECTS = 10;
- By convention, many Java programmers capitalize the entire names of class variables so that they're distinguished in code from other variables.
- This is not a requirement of the language, but is a practice that's recommended.
Creating Methods
- Top
- 127 As you learned on Day 3, "Working with Objects,"
- Chap 3: Class Methods
- methods define an object's behavior, anything that happens when the object is created as well as the various tasks the object can perform during its lifetime.
- 128 This section introduces method definitions and how methods work.
- Tomorrow's lesson has more details about more sophisticated things you can do with methods.
Defining Methods
- Top
- 128 In Java, a method definition has four basic parts
- The method's name
- A list of parameters
- The type of object or primitive type that the method returns
- The body of the method
- 128 The first two parts of the method definition form the method's signature
- 128 NOTE: To keep things simpler today, two optional parts of the method definition have been left out:
- a modifier, such as public or private, and the throws keyword, which indicates the exceptions a method can throw.
- You learn about these parts of method definition on Day 6, "Packages, Interfaces, and Other Class Features," and Day 7, "Exceptions and Threads."
- Top
- 128 In other languages, the name of the method (which might be called a function, subroutine, or procedure)
- is enough to distinguish it from other methods in the program.
- 128 In Java, you can have several methods in the same class with the same name but different signatures.
- This practice is called method overloading, and you learn more about it later today.
- Top
- 128 Here's what a basic method definition looks like:
returnType methodName(type1 arg1, type2 arg2, type3 arg3, ...){
// body of the method
}
- The returnType is the primitive type or class of the value returned by the method.
- It can be one of the primitive types, such as int or float, a class name, or void if the method does not return a value.
- The method's parameter list is a set of variable declarations separated by commas and set inside parentheses.
- These parameters become local variables in the body of the method, receiving their values when the method is called.
- Top
- 129 If a method returns an array object, the array brackets can go after either the return type or the closing parentheses of the parameter list.
- Because putting the brackets after the return type is easier to read, that approach is used in this book.
- For instance, the following declares a method that returns an integer array
int[] makeRange(int lower, int upper){
// body of the method
}
- Inside the body of the method, you can have statements, expressions, method calls on other objects, conditionals, loops, and so on.
- Unless a method has been declared with void as its return type, the method returns some kind of value when it is completed.
- This value must be explicitly returned at some exit point inside the method by using the return keyword.
- Top
- 129 Listing 5.1 contains RangeLister, a class that defines a makeRange() method.
- This method takes two integers, a lower boundary and an upper boundary, and creates an array that contains all the integers between those two boundaries.
- The boundaries themselves are included in the array of integers.
- Top
- 129 Create a new empty Java file in NetBeans for a class called RangerLister (package com.java21days) and enter the code of Listing 5.1 into it.
Listing 5.1
- Top
- page 129-130
package com.java21days;
class RangeLister {
int[] makeRange(int lower, int upper} {
int[] range = new int[(upper-lower) +1];
for (int i = 0; i < range.length, i++) {
range[i] = lower++;
}
return range;
}
public static void main(String[] arguments) {
int[] range;
RangeLister lister = new RangeLister();
range = lister.makeRange(4, 13);
System.out.print("The array: [ ");
for (int i = 0; i < range.length; i++) {
System.out.print(range[i] + " ");
}
System.out.println("]");
}
}
Run the program
- Top
- 130 Run the program by choosing Run, Run File in NetBeans to produce the output shown in Figure 5.1
Figure 5.1 goes here - output pane
- Top
- 130 The main() method in this class tests the makeRange() method by calling it with the arguments of 4 and 13.
- The method creates an empty integer array and uses a for loop to fill the new array with values from 4 through 13 in lines 7 - 9.
The this keyword
- Top
- 130 In the body of the method definition sometimes you need to refer to the object that contains the method (in other words, the object itself).
- You can do this to the object's instance variables and to pass the current object an an argument to another method.
- To refer to the object in its own method, use the this keyword where you normally would refer to an object's name.
- The this keyword refers to the current object, and you can use it anywhere a reference to an object might appear,
- in dot notation, as in argument to a method, as the return value for the current method, and so on.
- Here are examples of using this with comments to explain each one:
t = this.x; // the x instance variable for this object
z.resetDate(this); // call the resetDate method, defined in
// the z class, and pass it the current object
return.this; // return the current object
- In many cases, you might not need to explicitly use the this keyword because it is assumed.
- For instance, you can refer to both instance variables and method calls defined in the current class
- simply by name, because the this is implicit in those references.
- Therefore, you could write the first example as follows:
t = x; // the x instance variable for this object
- Top
- 131 NOTE: The viability of omitting the this keyword for instance variables
- depends on whether variables of the same name are declared in the local scope. You explore this further in the next section.
- 131 Because this is a reference to the current instance of a class, only use it inside the body of an instance method definition.
- Class methods, which are declared with the static keyword, cannot use this.
Variable Scope and Method Definitions
- Top
- 131 One thing you must know to use a variable is its scope.
- Scope is the part of a program in which a variable exists, making it possible to use the variable in statements and expressions.
- When the part defining the scope has finished executing, the variable ceases to exist.
- 131 When you declare a variable in Java, that variable always has limited scope.
- A variable with local scope, for example, can be used only inside the block in which it was defined.
- Instance variaables have a scope that extends to the entire class, so they can be used by any of the intance methods within that class,
- 131 When you refer to a variable, Java checks for its definition outward. starting with the innermost scope.
- The innermost scope could be a block statement, such as the contents of a while loop.
- The second-innermost scope could be the method in which the block is contained.
- If the variable hasn't been found in the method, the class itself is checked.
- Because of how Java checks for the scope of a given variable,
- it is possible for you to create a variable in a lower scope that hides (or replaces) the original value of that variable and introduces subtle bugs into your code.
- For example, consider the following Jva application:
class ScopeTest {
int test = 10;
void printTest() {
int test = 20;
System.out.println("Test: " + test);
}
public static void main(String[] arguments) {
scopeTest st = new ScopeTest();
st.printTest();
}
}
- 132 This class has two variables with the same name, test.
- The first, an instance variable, is initialized with the value 10.
- The second is a local variable with the value of 20.
- 132 The local variable test within the printTest() method hides the instance variable test in that scope.
- When the printTest() method is called within the main() method, it displays that test equals 20,
- even though there's a test instance variable that equals 10.
- You could avoid this problem by using this.test to refer to the instance variable and using test to refer to the local variable.
- 132 A more insidious example occurs when you redefine a variable in a subclass that already occurs in the superclass.
- This can create subtle bugs in your code.
- For example, you might call methods that are intended to change the value of an instance variable, but the wrong variable is changed.
- Another bug might occur when you cast an object from one class to another.
- The value of your instance variable might mysteriously change because the variable was getting that value from the superclass instead of your class.
- 132 The best way to avoid this behaviour is to be aware of the variables defined in the superclass of your class and avoid duplicating a variable name used higher in the class hierarchy.
Passing Arguments to Methods
- Top
- 132 When you call a method with an object as a parameter, the object is passed into the method's body as a reference to that object.
- Any change made to the object inside the method persists outside the method.
- Keep in mind that this includes arrays and all objects contained in arrays.
- When you pass an array into a method and modify its contents, the original array is affected.
- Primitive types and strings, on the other hand, are passed by value.
- You can't do anything in the method that changes those types.
Listing 5.2 The Full Text of Passer.java
- Top
- 132 The Passer class in Listing 5.2 demonstrates how this works.
- Create this class in NetBeans in the com.java21days package.
- page 133
package com.java21days;
class Passer {
void toUpperCast(String[] text) {
for (int i = 0; i < text.length, i++) {
text[i] = text[i].toUpperCase();
}
}
public static void main(String[] arguments) {
Passer passer = new Passer();
passer.toUpperCase(arguments);
for (int i = 0; i < arguments.length; i++) {
System.out.print(arguments[i] + " ");
}
System.out.println();
}
}
- 133 This application takes one or more command-line arguments and displays them in all uppercase letters.
- 133 In NetBeans, set the arguments by choosing Run, Set Project Configuration, Customize.
- The Project Properties dialog appears.
- Enter com.java21days.Passer as the Main Class and Athos Aramis Porthos (or words of your choosing) as Arguments and click OK.
- Run the application by choosing Run, Run Project.
- If you use the suggested arguments, the program produces the output shown in Figure 5.2
Figure 5.2 goes here
- Top
- 133 The Passer application uses command-line arguments stored in the arguments array of strings.
- 133 The application creates a Passer object and calls its toUpperCase() method with the arguments array as an argument (lines 12 - 13).
- Top
- 134 Because a reference to the array object is passed to the method, changing the value of each array element in Line 7 changes the actual element (rather than a copy of it).
- Displaying the array with lines 14 - 16 demonstrates this.
- Top
- 134 CAUTION: If nothing happens when you run the Passer Aplication in NetBeans, you're running it with the command Run, Run File instead of Run, Run Project.
- The Run File command does not use the arguments set up in the project configuration.
- The Run Project command does.
Class Methods
- Top
- 134 The relationship between class and instance variables is directly comparable to how class and instance methods work.
- Class methods are available to any instance of the class itself and can be made available to other classes.
- In addition, unlike an instance method, a class does not require an object of the class for its methods to be called.
- For example, the Java Class Library includes the System class, which defines a set of methods that are useful
- when displaying text, retrieving configuration information, and accomplishing other tasks.
- Here are two statements that use its class methods:
- System.exit(0);
- long now = System.currentTimeMillis();
- The exit(int) method closes an application with a status code that indicates success (0) or failure (any other value).
- The currentTimeMillis() method returns a long holding the number of milliseconds since midnight Jan. 1, 1970.
- This number is a representation of the current date and time.
- Top
- 134 To define class methods, use the static keyword in front of the method definition as you would in front of a class variable.
- For example, the class method exit() in the preceding example might have the following signature:
static void exit(int argument){
// body of the method
}
- Java supplies wrapper classes such as Integer and Float for each of the primitive types.
- By using class methods defined in those classes, you can create objects for primitive types, and vice versa.
- The same value is represented in either form.
- Top
- 135 For example, the parseInt() class method in the Integer class can be used with a string argument, returnng an int representation of that string:
- int count = Integer.parseInt("42");
- In this statement, parseInt() returns the String value "42" as an integer with a value of 42, which is stored in the count variable.
- The lack of a static keyword in front of a method name makes it an instance method.
- Instance methods operate in a particular object, rather than a class of objects.
- On Day 1, "Getting Started with Java," you created an instance method called checkTemperature() that checked the temperature in the robot's environment.
- Top
- 135 TIP: Methods that affect a particular object should be defined as instance methods.
- Methods that provide some general capability but do not directly affect an object of the class should be declared as class methods.
- 135 Class methods, unlike instance methods, are not inherited.
- A class method in a superclass cannot be overridden in a subclass.
Creating Java Applications
- Top
- 135 Now that you know how to create classes, objects, class and instance variables, and class and instance methods, you can put them all together in a Java program.
- A Java application consists of one or more classes and can be as large or as small as you want it to be.
- Although all the applications you've created up to this point do nothing visually other than display characters,
- you also can create Java applications that use windows, graphics, and a graphical user interface.
- The only thing you need to make a Java application run is one class that serves as the starting point.
- The class needs only one thing: a main() method.
- When the application is run, the Java Virtual Machine (JVM) calls this method.
- The signature for the main() methodtakes the following form:
public static void exit(String[] arguments){
// body of method
}
- Top
- 136 Here's a rundown of the parts of the main() method:
- public means that this method is available to other classes and objects, which is a form of access control.
- The main() method must be declared public.
- You learn more about access methods during Day 6.
- static means that main() is a class method
- void means that the main() method doesn't return a value
- main() takes one parameter, which is an array of strings.
- This argument holds command-line arguments.
- 136 The body of the main() method contains any code you need to start your application, such as the initialization of variables or the creation of objects.
- The main() method is a class method.
- An object of the class that holds main() is not created automatically when your application runs.
- If you want to treat that class as an object, you have to create an instance of it in the main() method (as you did in the Passer application in Listing 5.2 on line 12).
- 136 In a NetBeans project, one class can be designated as the main class of the project.
- When the project is packaged into a single Java archive (JAR) file, the main class will be run if the JAR file is executed.
- To set the main class, Choose Run, Set Project Configuration, Custimize.
- In the Project Properties dialog, enter the name of this class in the Main Class Field.
Helper Classes
- Top
- 136 Your Java application may consist of a single class, the one with the main() method, or several classses that use each other.
- (In reality, even a simple tutorial program uses numerous classes in the Java Class Library.)
- You can create as many classes as you want for your program.
- 136 As long as Java can find the class, your program uses it when it runs.
- Note, however, that only the starting-point class needs a main() method.
- After it is called, the methods inside the various classes and objects used in your program take over.
- Although you can include main() methods in helper classes, they are ignored when the program runs.
Java Applications and Arguments
- Top
- 136 Because Java applications are standalone programs, it's useful to pass arguments to an application to customize how it operates.
- 137 You can use arguments to determine how an application will run or to enable an application to operate on different kind of output.
- You can use program arguments for many purposes, such as to turn on debugging input or to indicate a filename load.
Passing Arguments to Java Applications
- Top
- 137 How to pass arguments to a Java application varies based on the environment and JVM on which Java is being run.
- To pass arguments to a Java program with the java interpreter included with the Java Development Kit (JDK),
- the arguments would be appended to the command line when the program is run.
- For example:
- java Echo April 450 -10
- Here java is the name of the interpreter, Echo is the Java application, and the rest are three arguments passed to a program: "April", "450", and "-10".
- Note that a space separates each of the arguments.
- To group arguments that have spaces in them, surround the arguments with quotation marks.
- For example, consider the following command line:
- java Echo Wilhelm Niekro Hough "Tim Wakefield" 49
- Putting quotation marks around "Tim Wakefield" causes that text to be treated as a single argument.
- The Echo application would receive five arguments: "Wilhelm", "Niekro", "Hough", "Tim Wakefield", and "49".
- The quotation marks prevent the space within "Tim Wakefield" from being used to separate arguments.
- Those spaces are not included as part of the argument when it is sent to the program and received using the main() method.
- Top
- 137 CAUTION: One thing quotation marks are not used for is to identify strings.
- Every argument passed to an application is stored in an array of Sting objects, even if it has a numeric value (such as 450, -10, and 49 in the preceding examples).
- Top
- 137 Because NetBeans runs the JVM behind the scenes, there's no command line on which to specify arguments.
- Instead, they can be set in the project configuration with the Run, Set Project Configuration, Customize command, as you did earlier to run the RangeLister application.
Handling Arguments in Your Java Application
- Top
- 138 When an application is run with arguments, Java stores the arguments as an array of strings and passes the array to the application's main() method.
- Take another look at the signature for main():
public static void exit(String[] arguments){
// body of method
}
- Here, arguments is the name of the array of strings that contains the list of arguments.
- You can call this array anything you want.
- Inside the main() method, you handle the arguments your program was given by looping through the array.
Listing 5.3
- Top
- 138 The Averager class in Listing 5.3 is a Java application that takes numeric arguments and returns the sum and average of those arguments.
- 138 Create a new empty Java file in NetBeans for the Averager class in the com.java21days package.
- page 138
package com.java21days;
class Averager {
public static void main(String[] arguments) {
int sum = 0;
if (arguments.length > 0) {
for (int i = 0; i < arguments.length; i++) {
sum += Integer.parceInt(arguments[i]);
}
System.out.println("Sum is: " + sum);
System.out.println("Average is: " +
(float) sum / arguments.length);
}
}
}
- Top
- 138 Before running the application in NetBeans, choose two or more numeric arguments in the project configuration,
- as you did with the RangeLister application
- They all should be integers.
- 138 The Averager application makes sure that in line 7 at least one argument is passed to the program.
- This is handled through length, the instance variable that contains the number of elements in the arguments array.
- 139 You must always do things like this when dealing with command-line arguments.
- Otherwise, your programs crash with ArrayIndexOutOfBoundsException errors whenever the user supplies fewer command-line arguments than you were expecting.
- 139 If at least one argument is passed to the application, the for loop iterates through all the strings stored in the arguments array (lines 8 - 10).
- Because all command-line arguments are passed to a Java appliication as String objects, you must convert them to numeric values before using them in any mathematical expressions.
- The parseInt() class method of the Integer class takes a String object as input and returns an int (line 9).
- If 75 1080 95 1316 were submitted as your arguments, you would see output matching Figure 5.3
Figure 5.3 goes here
- Top
- Figure 5.3 - Receiving arguments in an application.
run:
Sum is: 2566
Average is: 641.5
BUILD SUCCESSFUL (total time: 0 seconds)
Creating Methods with the Same Name
- Top
- 139 When you work with the Java Class Library, you often encounter classes that have numerous methods with the same name.
- 139 Two things differentiate these same-named methods:
- The number of arguments they take
- The primitive type or objects of each object
- 139 These two things are part of a method's signature.
- Using several methods with the same name and different signatures is called overloading.
- 139 Method overloading can eliminate the need for entirely different methods that do essentially the same thing.
- Overloading also makes it possible for methods to behave differently based on the arguments they receive.
- 139 When you call a method in an object, Java matches the method name and arguments to choose which definition to execute.
- Top
- 140 To create an overloaded method, you create different method definitions in a class, each with the same name but different argument lists.
- The difference can be the number, the type of argument, or both.
- Java allows overloading as long as each argument list is unique for the same method name.
- 140 CAUTION: Java does not consider the return type when differentiating among overloaded methods.
- If you attempt to create two methods with the same signiture and different return types, the class won't compile.
- In addition, the variable names that you choose for each argument to the method are irrelevant.
- The number and the type of arguments are the two things that metter.
- 140 The next project you undertake creates an overloaded method.
- It begins with a simple class definition for a class called Box.
- This defines a rectangular shape with four instance variables to define the upper-left and lower-right corners of the rectangle, (x1, y1) and (x2, y2):
class Box {
int x1 = 0;
int y1 = 0;
int x2 = 0;
int y2 = 0;
}
- When a new instance of the Box class is created, all its instance variables are initialized to 0.
- A BuildBox() instance method sets the variables to their correct values:
class BuildBox(int x1, int y1, int x2, int y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
return this;
}
- This method takes four integer arguments and returns a reference to the resulting Box object.
- Because the arguments have the same names as the instance variables, the keyword this is used inside the method when referring to the instance variables.
- This method can be used to create rectangles, but what if you wanted to define a rectangle's dimensions differently ?
- An alternative would be to use Point objects rather than individual coordinates, because Point objects contain both an x and y value as instance variables.
- Top
- 141 You can overload BuildBox() by creating a second version of the method with an argument list that takes two Point objects:
class BuildBox(Point topLeft, Point bottomRight) {
x1 = topLeft.x;
y1 = topLeft.y;
x2 = bottomRight.x;
y2 = bottomRight.y;
return this;
}
- For this method to work, the java.awt.Point class must be imported so that it can be referred to by the short name Point.
- Another possible way to define the rectangle is to use a top corner, a height, and a width:
class BuildBox(Point topLeft, int w, int h) {
x1 = topLeft.x;
y1 = topLeft.y;
x2 = (x1 + w);
y2 = (y1 + h);
return this;
}
- To finish this example, a printBox() method is created to display the rectangle's coordinates.
- A main() method turns Box into an application and tries out everything on a Box object.
- Top
- 141 Listing 5.4 shows the completed class definition.
- Create this class using NetBeans in package com.java21days.
Listing 5.4
- Top
- page 141-142
package com.java21days;
import java.awt.Point;
class Box {
int x1 = 0;
int y1 = 0;
int x2 = 0;
int y2 = 0;
Box buildBox(int x1, int y1, int x2, int y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
return this;
}
Box buildBox(Point topLeft, Point bottomRight) {
x1 = topLeft.x;
y1 = topLeft.y;
x2 = bottomRight.x;
y2 = bottomRight.y;
return this;
}
Box BuildBox(Point topLeft, int w, int h) {
x1 = topLeft.x;
y1 = topLeft.y;
x2 = (x1 + w);
y2 = (y1 + h);
return this;
}
void printBox() {
System.out.print("Box: <" + x1 + ", " + y1);
System.out.println(", " + x2 + ", " + y2 + ">");
}
public static void main(String[] arguments) {
Box rect = new Box();
System.out.println("Calling buildBox with "
+ "coordinates (25,25) and (50,50):");
rect.buildBox(25, 25, 50, 50);
rect.printBox();
System.out.println("\nCalling buildBox with "
+ "points (10,10) and (20,20):");
rect.buildBox(new Point(10, 10), new Point(20, 20);
rect.printBox();
System.out.println("\nCalling buildBox with "
+ "point (10,10), width 50 and height 50:");
rect.buildBox(new Point(10, 10), 50, 50);
rect.printBox();
}
}
Figure 5.4 goes here - Output pane from NetBeans
- Top
- 143 Run the application to see the output depicted in Figure 5.4
run:
Calling buildBox with coordinates (25,25) and (50,50):
Box: <25, 25, 50, 50>
Calling buildBox with points (10,10) and (20,20):
Box: <10, 10, 20, 20>
Calling buildBox with point (10,10), width 50 and height 50):
Box: <10, 10, 60, 60>
BUILD SUCCESSFUL (total time: 0 seconds)
- Top
- 143 You can define as many versions of a method as you need to implement the behaviou needed for that class.
- 143 When you have several methods that do similar things, using one method to call another is a shortcut technique to consider.
- For example, the buildBox() method in lines 19 - 25 can be replaced with the following, much shorter, method:
Box buildBox(Point topLeft, Point bottomRight) {
return buildBox(topLeft.x, topLeft.y,
bottomRight.x, bottomRight.y);
}
- The return statement in this method calls the buildBox() method in lines 11 - 17 with four integer arguments,
- producing the same result in fewer statements.
- This application uses a programming shortcut for working with objects that hasn't been employed up to this point.
- Take a look at line 56:
rect.buildBox(new Point(10, 10), 50, 50);
- The new operator is used as an argument to a method.
- This makes the argument the object created by calling that constructor,
- which is possible in Java because calling new is an expression whose value is the newly created object.
- The preceding statement accomplishes the same thing as these two lines of code:
Point rectangle = new Point(10, 10), 50, 50); <why is there one too many right parentheses>
rect.buildBox(new Point(10, 10), 50, 50);
- The one-line version is more efficient because it doesn't store an object in a variable that will be used only once and never needs to be accessed in any subsequent code.
- You will find this shortcut employed often in Java programs.
Constructors
- Top
- 144 You also can define constructors in your class definition that are called automatically when objects of that class are created.
- A contructor is a method called on an object when it is created, in other words, when it is constructed
- 144 Unlike other methods, a constructor cannot be called directly.
- Java does three things when the new is used to create an instance of a class:
- It allocates memory for the object.
- It initializes that object's instance variables, either to initial values
- or to a default (0 for numbers, null for objects, false for Booleans, or '\0' for characters).
- It calls a constructor of the class.
- If a class doesn't have any constructors defined, an object still is created when the new operator is used in conjunction with the class.
- However, you might have to set its instance variables or call other methods that the object needs to initialize itself.
- When an object is created of a class that has no constructors, a constructor with no arguments is implicity provided by Java.
- This constructor is called to create the object.
- For this reason, a constructor with no arguments can be called with new even when no constructors are defined.
- By defining constructors in your own classes,
- you can set initial values of instance variables,
- call methods based on those variables,
- call methods on other objects,
- and set an object's initial properties.
- When creating a class, you can overload constructors, as you can do with methods, to create an object that has specific properties based on the arguments you give to new.
- If a class has a constructor that takes one or more arguments, a constructor with no arguments can be called only if one has been defined in the class.
Basic Constructors
- Top
- 144 Constructors look a lot like regular methods, with three basic differences:
- They always have the same name as the class.
- They don't have a return type.
- They cannot return a value in the method by using the return statement.
- 145 For example, the following class uses a constructor to initialize its instance variables based on arguments for new:
class MarsRobot {
String status;
int speed;
int power;
MarsRobot(String in1, int in2, int in3) {
status = in1;
speed = in2;
power = in3;
}
}
- You could create an object of this class with the following statement:
- MarsRobot curiosity = new MarsRobot("exploring", 5, 200);
- The status instance variable would be set to "exploring", speed to 5, and power to 200.
Calling Another Constructor
- Top
- 145 If you have a constructor that duplicates some of the behavior of an existing constructor, you can call the first constructor from inside the body of the second.
- Java provides special syntax for doing this.
- Use the following code to call a constructor defined in the current class:
- this(argument1, argument2, argument3);
- 145 The use of this with a constructor is similar to how this can be used to access a current object's variable.
- In the preceding statement, arguments with this() are the arguments for the constructor.
- 145 For example, consider a simple class that defines a circle using the (x,y) coordinate of its center and the length of its radius.
- The class, Circle, could have two constructors: one where the radius is defined and one where the radius is set to a default value of 1.
- Here's code that does this:
class Circle {
int x, y, radius;
Circle(int xPoint, int yPoint, int radiusLength) {
this.x = xPoint;
this.y = yPoint;
this.radius = radiusLength;
}
Circle(int xPoint, int yPoint) {
this(xPoint, yPoint, 1);
}
}
- Top
- 146 The second constructor in Circle takes only the (x,y) coordinates of the circle's center.
- Because no radius is defined, the default value of 1 is used.
- The first constructor is called with the arguments xPoint, yPoint, and the integer literal 1.
Overloading Constructors
- Top
- 146 Like methods, constructors also can take varying numbers and types of arguments.
- This capability enables you to create an object with exactly the properties you want it to have,
- or as an alternative, allows the object to calculate properties from different kinds of input.
- For example, the buildBox() methods that you defined in the Box class earlier today
- would make excellent constructors because they are used to initialize an object's instant variables to the appropriate values.
- So, instead of the original buildBox() method you defined (which took four arguments for the corners' coordinates), you could create a constructor.
Listing 5.5
- Top
- page 146-147
package com.java21days;
import java.awt.Point;
class Box2 {
int x1 = 0;
int y1 = 0;
int x2 = 0;
int y2 = 0;
Box2 buildBox(int x1, int y1, int x2, int y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
Box2(Point topLeft, Point bottomRight) {
this(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
}
Box2(Point topLeft, int w, int h) {
this(topLeft.x, topLeft.y, topLeft.x + w, topLeft.y + h);
}
void printBox() {
System.out.print("Box: <" + x1 + ", " + y1);
System.out.println(", " + x2 + ", " + y2 + ">");
}
public static void main(String[] arguments) {
Box2 rect;
System.out.println("Calling Box2 with coordinates "
+ "(25,25) and (50,50):");
rect = new Box2(25, 25, 50, 50);
rect.printBox();
System.out.println("\nCalling buildBox with points "
+ "(10,10) and (20,20):");
rect = new Box2(new Point(10, 10), new Point(20, 20));
rect.printBox();
System.out.println("\nCalling Box2 with 1 point "
+ "(10,10), width 50 and height 50:");
rect = new Box2(new Point(10, 10), 50, 50);
rect.printBox();
}
}
- Top
- 147 This application produces the same output as the Box application shown in Figure 5.4.
- In Listing 5.5, the second and third constructors use this in lines 19 - 20 and lines 24 - 25
- to call the first constructor, giving it the task of creating the object with the specified parameters.
Overriding Methods
- Top
- 147 When you call an object's method, Java looks for that method definition in the object's class.
- If it doesn't find it, the method is sought in the object's superclass, and on up the class hierarchy until a method definition is found.
- Inheritance enables you to define and use methods repeatedly in subclasses without having to duplicate the code.
- 148 However, there might be times when you want an object to respond to the same method but have different behavior when that method is called.
- In that case, you can override the method.
- To do this, define a method in a subclass with the same signature as a method in a superclass.
- Then, when the method is called, the subclass method is found and executed instead of the one in the superclass.
- This is called overriding a method.
Creating Methods That Override Existing Methods
- Top
- 148 To override a method, all you have to do is create a method in your subclass that has the same signature (name and argument list) as a method defined by your class's superclass.
- Because Java executes the first method definition it finds that matches the signature, the new signature hides the original method definition.
- 148 Here's a simple example. Listing 5.6 contains two classes.
- Printer contains a method called printMe() that displays information about objects of that class.
- SubPrinter is a subclass that adds a z instance variable to the class.
- Create this class and name it Printer in NetBeans (package: com.java21days).
Listing 5.6
- Top
- page 148
package com.java21days;
class Printer {
int x = 0;
int y = 1;
void printMe() {
System.out.println("x is " + x + ", y is " + y);
System.out.println("I am an instance of the class " +
this.getClass().getName());
}
}
class SubPrinter extends Printer {
int z = 3;
public static void main(String[] arguments) {
SubPrinter obj = new SubPrinter();
obj.printMe();
}
}
- Top
- 149 When this file is compiled, there are two classes rather than one.
- Because the source file defines the Printer and SubPrinter classes, the compiler produces both.
Run SubPrinter
- Top
- 149 Run SubPrinter (by selecting Run, Run File in NetBeans), and you see the output in Figure 5.5
Figure 5.5 goes here
- Top
- 149 CAUTION: The Printer class does not have a main() method, so it cannot be run as an application.
- So when you choose Run, Run File in NetBeans, it automatically runs the SubPrinter application's main() method, because no other class has such a method.
- If a source code file contains more than one class with main(), NetBeans asks which one should be run.
- Top
- 149 In the application, a SubPrinter object was created and the printMe() method was called in the main() method of SubPrinter.
- Because the SubPrinter does not define this method, Java looks for it in the superclasses of SubPrinter, starting with Printer.
- Printer has a printMe() method, so it is executed.
- Unfortunately, this method does not display the z instance variable, as you can see from the preceding output.
- The superclass does not define this variable, so it could not display it.
- 149 To correct this problem, you can override the printMe() method in SubPrinter, adding a statement to display the z instance variable:
void printMe() {
System.out.println("x is " + x + ", y is " + y +
", z is " + z);
System.out.println("I am an instance of the class " +
this.getClass().getName());
}
Calling the Original Method
- Top
- 149 Usually, there are two reasons why you want to override a method that a superclass already has implemented:
- To replace the definition of that original method
- To augment the original method with additional behavior
- 150 Overriding a method and giving it a new definition hides the original method definition.
- However, sometimes behavior should be added to the original definition instead of being replaced,
- particularly when behavior is duplicated in both the original method and the method that overrides it.
- By calling the original method in the body of the overriding method, you can add only what you need.
- Top
- 150 Use the super keyword to call the original method from inside a method definition.
- This keyword passes the method call up the hierarchy, as shown in the following:
void doMethod(String a, String b) {
// do stuff here
super.doMethod(a, b);
// do more stuff here
this.getClass().getName());
}
- The super keyword, similar to the this keyword, is a placeholder for the class's superclass.
- You can use it anywhere that you use this, but super refers to the superclass rather than the current object.
Overriding Constructors
- Top
- 150 Technically, constructors cannot be overriden.
- Because they always have the same name as the current class, new constructors are created instead of being inherited.
- This system is fine much of the time, when your class's constructor is called, the constructor with the same signature for all your superclasses also is called.
- Therefore, initialization can happen for all parts of a class you inherit.
- 150 However, when you are defining constructors for your own class,
- you might want to change how your object is initialized,
- not only by initializing new variables added by your class,
- but also by changing the contents of variables that are already there.
- To do this, explicity call the constructors of the superclass, and change whatever variables need to be changed
- 150 To call a regular method in a superclass, you use super.methodname(arguments).
- Because constructor methods don't have a method name to call, the following form is used:
- super(argument1, argument2, ...);
- reserve
- 151 Java has a rule for the use of super(), It must be the first statement in your constructor definition.
- If you don't call super() explicity in that first statement, Java automatically calls super() with no arguments before the first statement in the constructor.
- 151 Because a call to a super() method must be the first statement, you can't do something like the following in your constructor:
if (condition == true) {
super(1,2,3); // call one superclass constructor
} else {
super(1,2); // call a different constructor
}
- Similar to using this() in a constructor, super() calls the constructor for the immediate superclass (which might, in turn, call the constructor of its superclass, and so on).
- Note that a constructor with that signature has to exist in the superclass for the call to super() to work.
- The Java compiler checks this when a class is compiled.
- You don't have to call the constructor in your superclass that has the same signature as the constructor in your class,
- you have to call the constructor only for the values you need initialized.
- In fact, you can create a class that has constructors with entirely different signatures from any of the superclass's constructors.
- Top
- 151 Listing 5.7 shows a class called NamedPoint, which extends the class Point from the java.awt package.
- The Point class has only one constructor, which takes an x and a y argument and returns a Point object.
- NamedPoint has an additional instance variable (a string for a name) and defines a constructor to initialize x,y, and the name.
- Create this class in NetBeans in the com.java21days package.
Listing 5.7
- Top
- page 151-152
package com.java21days;
class NamedPoint extends Point {
String name;
NamedPoint(int x, int y, String name) {
super(x, y);
this.name = name;
}
public static void main(String[] arguments) {
NamedPoint np = new NamedPoint(5, 5, "SmallPoint");
System.out.println("x is " + np.x);
System.out.println("y is " + np.y);
System.out.println("Name is " + np.name);
}
}
- Top
- 152 The output is displayed in Figure 5.6
Figure 5.6 goes here
- Top
- 152 The constructor defined for NamedPoint calls Point's constructor to initialize the instance variables of Point(x and y).
- Although you can just as easily initialize x and y yourself, you might not know what other things Point is doing to initialize itself.
- Therefore, it is always a good idea to pass constructors up the hierarchy to make sure that everything is set up correctly.
Summary
- Top
- 152 After finishing today's lesson, you should have a pretty good idea of the relationship among classes in Java and programs you create using the language.
- Everything you create in Java involves the use of a main class that interacts with other classes as needed.
- During this day, you put together everything you have learned about creating Java classes.
- 152 These topics were covered:
- Instance and class variables, which hold the attributes of a class and objects created from it
- Instance and class methods, which define the behavior of a class.
- You learned how to define methods,
- including the parts of a method signature,
- how to return values from a method,
- how arguments are passed to methods,
- and how to use the this keyword to refer to the current object.
- The main() method of Java applications, and how to pass arguments to it
- Overloaded methods, which reuse a method name by giving it different arguments
- Constructors, which define the initial variables and other starting conditions of an object
Q & A
- Top
- Q My class has an instance variable called origin.
- It also has a local variable called origin, in a method, which, because of variable scope, gets hidden by the local variable.
- Is there any way to access the instance variable's value ?
- A The easiest way to avoid this problem is to give your local variables different names than your instance variables.
- If for some reason you prefer to call a local variable origin when there's an instance variable of the same name,
- you can use this.origin to refer to the instance variable and origin to refer to the local variable.
- Q I created two methods with the following statement.
- int total(int arg1, int arg2, int arg3 { ... }
float total(int arg1, int arg2, int arg3 { ... }
- The Java compiler complains when I try to compile the class with these method definitions, even though their signatures are different.
- What did I do wrong ?
- A Your methods have the same signature.
- Method overloading in Java works only if the argument lists are different in either number or type of arguments.
- Return type is not part of a method signature, so it's not considered when methods have been overloaded.
- Looking at it from the point at which the method is called, this makes sense:
- If two methods have exactly the same argument lists, how would Java know which one to call?
- Q I wrote a program to take four arguments, but when I give it too few arguments, it crashes with a runtime error. Why ?
- A It's up to you to test for the number and type of arguments your program expects, Java won't do it for you.
- If your program requires four arguments,
- test in the main() method that you have indeed been given four arguments by using the length variable of an array,
- which contains the count of its elements.
- Return an error message if you haven't and end the program.
Quiz - Questions
- If a local variable has the same name as an instant variable, how can you refer to the instance variable in the scope of the local variable ?
- You can't, you should rename one of the variables.
- Use the keyword this before the instance variable name.
- Use the keyword super before the name.
- Where are instance variables declared in a class?
- Antwhere in the class
- Outside all methods in the class
- After the class declaration and above the first method
- How can you send to a program an argument that includes a space or spaces ?
- Surround the argument with double quotes.
- Separate the arguments with commas.
- Separate the arguments with periods.
Answers
- Top | Note A is 1, B is 2, and C is 3
- B. Answer A is a good idea, but variable name conflicts can be a source of subtle errors in your Java program.
- B. Customarily, instance variables are declared right after the class declaration and before any methods. It's necessary only that they be outside all methods.
- A. The quotation marks are not included in the argument when it is passed to the program.
Certification Practice
- Top
- 154 The following question is the kind of thing you could expect to be asked on a Java programming certification test. Answer it without looking at today's material or using the Java compiler to test the code.
- The answer is available on the book's website at www.java21days.com
- Given:
public class BigValue {
float result;
public BigValue(int a, int b) {
result = calculateResult(a, b);
}
float calculateResult(int a, int b) {
return (a * 10) + (b * 2);
}
public static void main(String[] arguments) {
BiggerValue bgr = new BiggerValue(2, 3, 4);
System.out.println("The result is " + bgr.result);
}
}
class BiggerValue extends BigValue {
BiggerValue(int a, int b, int c) {
super(a, b);
result = calculateResult(a, b, c);
}
// answer goes here
return (c * 3) * result;
}
}
- What statement should replace the // answer goes here so that the result variable equals 312.0 ?
- float calculateResult(int c) {
- float calculateResult(int a, int b) {
- float calculateResult(int a, int b, int c) {
- float calculateResult() {
Exercise
- Top
- To extend your knowledge of the subjects covered today, try the following exercises:
- Modify the MarsRobot project from Day 1 so that it includes constructors.
- Create a class for four-dimensional points called FourDPoint that is a subclass of Point from the java.awt package.