1. Understanding Method Calls and Placement

    A method is a program module that contains a series of statements that carry out a task. You have already seen Java classes that contain a main() method, which executes automatically when you run a program. A program’s main() method can execute additional methods, and those methods can execute others. Any class can contain an unlimited number of methods, and each method can be called an unlimited number of times. To execute a method, you invoke or call it. In other words, a calling method (also known as a client method) invokes a called method. Consider the simple First class that you saw in Chapter 1; it displayed a single line of output, First Java application. Suppose that you want to add three lines of output to this application to display your company’s name and address. One approach would be to simply add three new println() statements, as shown in Figure.
    public class First { public static void main(String[] args) { System.out.println("XYZ Company"); System.out.println("8900 U.S. Hwy 14"); System.out.println("Crystal Lake, IL 60014"); System.out.println("First Java application"); } }
    Instead of adding the three println() statements to the application in previous Figure, you might prefer to call a method that executes the three statements. Then the program would look like the one in Figure that calls the displayAddress() method. The order in which methods appear in a class has no bearing on the order in which the methods are called or execute. No matter where you place it, the main() method is always executed first in any Java application, and it might call any other methods in any order and any number of times. The order in which you call methods, not their physical placement, is what makes a difference in how an application executes. A main() method executes automatically when you run a program, but other methods do not execute simply because you place them within a class—they must be called.
    public class First { public static void main(String[] args) { displayAddress(); System.out.println("First Java application"); } public static void displayAddress() { System.out.println("XYZ Company"); System.out.println("8900 U.S. Hwy 14"); System.out.println("Crystal Lake, IL 60014"); } }
  2. IUnderstanding Method Construction

    Every method must include the two parts featured in Figure • A method header—A method’s header provides information about how other methods can interact with it. A method header is also called a declaration. • A method body between a pair of curly braces—The method body contains the statements that carry out the work of the method. In Figure 3-6, the main() method contains two statements, and the displayAddress() method body contains three statements. A method’s body is called its implementation. Technically, a method is not required to contain any statements in its body, but you usually would have no reason to create an empty method in a class. (Sometimes, while developing a program, the programmer creates an empty method as a placeholder and fills in the implementation later. An empty method is called a stub.)
    public class First { public static void main(String[] args) // Method header { displayAddress(); System.out.println("First Java application"); // Method body } public static void displayAddress() // Method header { System.out.println("XYZ Company"); System.out.println("8900 U.S. Hwy 14"); System.out.println("Crystal Lake, IL 60014"); // Method body } }
    The method header is the first line of a method. It contains the following: • Optional access specifiers • A return type • An identifier • Parentheses The next few figures compare these parts of a method header for the main() method and the displayAddress() method in the First class.
    Access Specifiers
    Figure highlights the optional access specifiers for the two methods in the First class. The access specifier for a Java method can be any of the following modifiers: public, private, protected, or, if left unspecified, package by default. Most often, methods are given public access; this book will cover the other modifiers later. Endowing a method with public access means that any other class can use it, not just the class in which the method resides.
    The main() method in an application must specify public access. public static void main(String[] args) The static modifier means that these methods do not require an object to be created. The displayAddress() method is not required to specify public access. However, if access is public, the method can be used by other, outside classes. public static void displayAddress() In addition, any method that can be used without instantiating an object requires the keyword modifier static. The main() method in an application must use the keyword static, but other methods, like displayAddress(), can use it too. You will learn about nonstatic methods later in this chapter.
    Figure features the return types for the main() and displayAddress() methods in the First class. A return type describes the type of data the method sends back to its calling method. Not all methods return a value to their calling methods; a method that returns no data has a return type of void. The main() method in an application must have a return type of void; in this example, displayAddress() also has a void return type. Other methods that you will see later in this chapter have different return types. The phrases void method and method of type void both refer to a method that has a void return type. The main() method in an application must have a void return type. public static void main(String[] args) The displayAddress() method does not send any information back to the method that calls it, so its return type is void. Later in this chapter you will write methods with other return types. public static void displayAddress()
    Method Name
    Figure highlights the names of the two methods in the First class. A method’s name can be any legal identifier. That is, like identifiers for classes and variables, a method’s identifier must be one word with no embedded spaces, and cannot be a Java keyword. The method that executes first when you run an application must be named main(), but you have a lot of leeway in naming other methods that you create. Technically, you could even name another method main() as long as you did not include String[] within the parentheses, but doing so would be confusing and is not recommended. Because methods “do” something—that is, perform an action—their names frequently contain a verb, such as print or compute. public static void main(String[] args) The method that executes first when you run an application must be named main(). Other methods you write in a class can have any legal identifier. public static void displayAddress()
    As previous figure shows, every method header contains a set of parentheses that follow the identifier. The parentheses might contain data to be sent to the method. For example, when you write a main() method in a class, the parentheses in its header surround String[] args. The displayAddress() method in the First class requires no outside data, so its parentheses are empty. Later in this chapter, you will see several methods that accept data. The main() method in an application must contain String[] and an identifier (args is traditional) within its parentheses. public static void main(String[] args) Other methods you write might accept data within their parentheses, but displayAddress()does not. public static void displayAddress() The full name of the displayAddress() method is First.displayAddress(), which includes the class name (First), a dot, and the method name, which is displayAddress(). (The name does not include an object because displayAddress() is a static method.) A complete name that includes the class is a fully-qualified identifier. When you use a method within its own class, you do not need to use the fully qualified name (although you can); the simple method name alone is enough. However, if you want to use a method in another class, the compiler does not recognize the method unless you use the full name. You have used similar syntax (including a class name, dot, and method name) when calling the JOptionPane.showMessageDialog() method. Each of two different classes can have its own method named displayAddress(). Such a method in the second class would be entirely distinct from the identically named method in the first class. You could use both methods in a third class by using their fully qualified identifiers. Two classes in an application cannot have the same name.
  3. Adding Parameters to Methods
    Some methods require that data items be sent to them when they are called. Data items you use in a call to a method are called arguments. When the method receives the data items, they are called parameters. Methods that receive data are flexible because they can produce different results depending on what data they receive. As a real-life example, when you make a restaurant reservation, you do not need to employ a different method for every date of the year at every possible time of day. Rather, you can supply the date and time as information to the person who carries out the method. The method, recording the reservation, is then carried out in the same manner, no matter what date and time are supplied. In a program, if you design a method to square numeric values, it makes sense to design a square() method that you can supply with an argument that represents the value to be squared, rather than having to develop a square1() method (that squares the value 1), a square2() method (that squares the value 2), and so on. To call a square() method that takes an argument, you might write a statement like square(17); or square(86);. Similarly, any time it is called, the println() method can receive any one of an infinite number of arguments—for example, “Hello”, “Goodbye”, or any other String. No matter what message is sent to println(), the message is displayed correctly. If the println() method could not accept arguments, it would not be practical to use. In everyday life, you use many methods without understanding how they work. For example, when you make a real-life restaurant reservation, you do not need to know how the reservation is actually recorded at the restaurant—perhaps it is written in a book, marked on a large chalkboard, or entered into a computerized database. The implementation details don’t concern you as a client, and if the restaurant changes its methods from one year to the next, the change does not affect your use of the reservation method—you still call and provide your name, a date, and a time. Similarly, object-oriented programs use implementation hiding, which describes the encapsulation of method details. It means that a client does not have to know how a method works internally, but only needs to know the name of the called method and what type of information to send. (Usually, you also want to know about any data returned by the method; you will learn about returned data later in this chapter.) In other words, the calling method needs to understand only the interface to the called method. The interface is the only part of a method that the method’s client sees or with which it interacts. In addition, if you substitute a new or revised method implementation, as long as the interface to the method does not change, you won’t need to make any changes in any methods that call the altered method.
    Creating a Method that Receives a Single Parameter
    Whether or not a method can receive a parameter, its declaration contains the same elements as one that does not accept a parameter—optional access specifiers, the return type for the method, the method name, and a set of parentheses. However, if a method receives a parameter, two additional items are required within the parentheses: • The parameter type • A local name for the parameter For example, you might want to create a method to compute gross pay based on a standard hourly pay rate; gross pay is the number of hours an employee worked multiplied by the hourly pay rate before any deductions such as payroll taxes are taken. The declaration for a public method named calculateGross() that accepts a value for an employee’s hours worked could be written as follows: public static void calculateGross(double hours) You can think of the parentheses in a method declaration as a funnel into the method— parameters listed there contain data that is “dropped into” the method. A parameter accepted by a method can be any data type, including the primitive types, such as int, double, and char; it also can be a built-in class type such as String or PrintStream, or a class type you create. In the method header for calculateGross(), the parameter double hours within the parentheses indicates that the method will receive a value of type double, and that within the method, the passed value will be known as hours. Figure 3-13 shows a complete method that uses an hourly pay rate of $13.75. The calculateGross() method is a void method because it does not need to return a value to any other method that calls it—its only function is to receive the hours value, multiply it by the STD_RATE constant, and then display the result. public static void calculateGross(double hours) // Parameter data type and parameter identifier { final double STD_RATE = 13.75; double gross; gross = hours * STD_RATE; System.out.println(hours + " hours at $" + STD_RATE + " per hour is $" + gross); } The calculateGross() method’s parameter is a double, so you call it using any argument that can be promoted to a double. In other words, it can accept a variable, constant, or expression that is a double, float, long, int, short, or byte. (See Figure 2-41 in Chapter 2 to review the order for establishing unifying data types.) For example, all of the following method calls are valid: • calculateGross(10);—This call uses an unnamed int constant that is promoted to a double. • calculateGross(28.5);—This call uses an unnamed double constant. • calculateGross(7.5 * 5);—This call uses an arithmetic expression. • calculateGross(STANDARD_WORK_WEEK);—This call uses a named constant that might be a double, float, long, int, short, or byte. • calculateGross(myHours);—This call uses a variable that might be a double, float, long, int, short, or byte. • calculateGross(getGross());—This call assumes that the getGross() method returns a double, float, long, int, short, or byte. You learn about methods that return data later in this chapter. You can call the calculateGross() method any number of times, with a different argument each time. Each of these arguments becomes known as hours within the method. The identifier hours represents a variable that holds a copy of the value of any double value passed into the method. It is interesting to note that if the value used as an argument in the method call to calculateGross() is a variable, it might possess the same identifier as hours or a different one, such as timeWorked. The parameter hours is a local variable to the calculateGross() method; that is, it is known only within the boundaries of the method. The variable and constant declared within the method are also local to the method.
    public class DemoGrossPay { public static void main(String[] args) { double hours = 25; double yourHoursWorked = 37.5; calculateGross(10); // The calculateGross() method is called three times using three different arguments. calculateGross(hours); calculateGross(yourHoursWorked); } public static void calculateGross(double hours) // Each time the method is called, the parameter hours receives a copy of the value that was passed. { final double STD_RATE = 13.75; double gross; gross = hours * STD_RATE; System.out.println(hours + “ hours at $” + STD_RATE + “ per hour is $” + gross); } }
    Creating a Method that Requires Multiple Parameters
    A method can require more than one parameter. For example, rather than creating a calculateGross() method that uses a standard hourly rate of $13.75 for every employee, you might prefer to create a method to which you can pass two values—the hours worked as well as an hourly rate. Figure shows a method that uses two such parameters.
    public static void calculateGross(double hours, double rate) // Each parameter requires a data type and an identifier and are separated with a comma. { double gross; gross = hours * rate; System.out.println(hours + " hours at $" + rate + " per hour is $" + gross); } You can write a method so that it takes any number of parameters in any order. However, when you call a method, the arguments you send to a method must match in order—both in number and in type—the parameters listed in the method declaration. Although the calculated gross pay is the same either way, the call calculateGross(10, 20); results in output describing 10 hours worked at $20 per hour, but calculateGross(20, 10); results in output describing 20 hours worked at $10 per hour. If arguments to a method are passed in the wrong order, the result is one of the following: • If the method can still accept all the arguments, the result is a logical error; that is, the program compiles and executes, but it probably produces incorrect results. • If the method cannot accept the arguments, passing arguments in the wrong order constitutes a syntax error, and the program does not compile. For example, if you try to pass a double value to a method that accepts an int parameter, the program fails to compile. A method’s signature is the combination of the method name and the number, types, and order of arguments. Therefore, you can say that a method call must match the called method’s signature.
  4. Creating Methods that Return Values

    A method ends when any of the following events takes place: • The method completes all of its statements. You saw methods like this in the last section. • The method throws an exception. Exceptions are errors; you will learn about them in the chapter “Exception Handling.” • The method reaches a return statement. A return statement causes a method to end and the program’s logic to return to the calling method. Also, a return statement frequently sends a value back to the calling method. The return type for a method can be any type used in Java, which includes the primitive types int, double, char, and so on, as well as class types (including class types you create). Of course, as you have seen in several examples so far, a method also can return nothing, in which case the return type is void. A method’s return type is known more succinctly as a method’s type. For example, the declaration for the displayAddress() method shown earlier in Figure 3-4 is written as follows: public static void displayAddress() This method returns no value, so it is type void. A method that prompts a user for an age and returns the age to the calling method might be declared as: public static int getAge() The method returns an int, so it is type int. As another example, a method that returns true or false depending on whether an employee worked overtime hours might be declared as: public static boolean didWorkOvertime() This method returns a Boolean value, so it is type boolean. The calculateGross() method shown earlier produces output, but does not return any value, so its return type is void. If you want to create a method to return the new, calculated salary value rather than display it, the header would be written as shown public static double calculateGross(double hours, double rate) { double gross; gross = hours * rate; return gross; // The value that is returned } For example, a method with a double return type might have a return statement that looks like either of the following: return 1; return 1.0; Additionally, if the types are compatible, a method might return a variable, a named constant, a call to another method, or the result of a calculation, as in the following examples: return myHoursWorked; return MAXIMUM_PAY; return getHours(); return myRate * 1.2; You cannot place any statements after a method’s return statement. Such statements are unreachable statements because the logical flow leaves the method at the return statement. An unreachable statement can never execute, and it causes a compiler error. Unreachable statements are also called dead code. If a method returns a value, then when you call the method, you normally use the returned value, although you are not required to do so. For example, when you invoke the calculateGross() method, you might want to assign the returned value (also called the method’s value) to a double variable named myPay, as in the following statement: myPay = calculateGross(myHoursWorked, myRate); Alternatively, you can choose to use a method’s returned value directly, without storing it in any variable. When you use a method’s value, you use it in the same way you would use any variable of the same type. For example, you can display a method’s returned value from within a println() method call as in the following: System.out.println("My pay is " + calculateGross(myHoursWorked, myRate));
    Chaining Method Calls
    public static double calculateNetPay(double hours, double rate) { double gross; double withholding; double net; gross = calculateGross(hours, rate); // Call to calculateGross() withholding = calculateWithholding(gross); // Call to calculateWithholding() net = gross - withholding; return net; } You also can chain method calls in a single statement. If you create methods named getHours() and getRate(), and each return a double, then you might want to call calculateNetPay() as follows: double net = calculateNetPay(getHours(), getRate());
    Using the Enhanced for Loop with Objects
    You can use the enhanced for loop to cycle through an array of objects. For example, to display data for seven Employees stored in the emps array, you can write the following: for(Employee worker : emps) System.out.println(worker.getEmpNum() + " " + worker.getSalary()); In this loop, worker is a local variable that represents each element of emps in turn. Using the enhanced for loop eliminates the need to use a limiting value for the loop and eliminates the need for a subscript following each element.
    Manipulating Arrays of Strings
    As with any other object, you can create an array of String objects. For example, you can store three company department names as follows: String[] deptNames = {"Accounting", "Human Resources", "Sales"}; You can access these department names with a subscript like any other array object. For example, you can use the following code to display the list of Strings stored in the deptNames array: for(int a = 0; a < deptNames.length; ++a) System.out.println(deptNames[a]); Notice that deptNames.length; refers to the length of the array deptNames (three elements) and not to the length of any String objects stored in the deptNames array. Remember: • Arrays use a length field (no parentheses follow). • String objects use a length() method. For example, if deptNames[0] is Accounting, then deptNames[0].length() is 10 because Accounting contains 10 characters.
  5. Learning About Classes and Objects

    When you think in an object-oriented manner, everything is an object, and every object is a member of a class. You can think of any inanimate physical item as an object—your desk, your computer, and the building in which you live are all called objects in everyday conversation. You also can think of living things as objects—your houseplant, your pet fish, and your sister are objects. Events are also objects—the stock purchase you made, the mortgage closing you attended, and a graduation party that was held in your honor are all objects. Everything is an object, and every object is a member of a more general class. Your desk is a member of the class that includes all desks, and your pet fish is a member of the class that contains all fish. An object-oriented programmer would say that your desk is an instance of the Desk class and your fish is an instance of the Fish class. These statements represent is-a relationships—that is, relationships in which the object “is a” concrete example of the class. Expressing an is-a relationship is correct only when you refer to the object and the class in the proper order. You can say, “My oak desk with the scratch on top is a Desk, and my goldfish named Moby is a Fish.” You don’t define a Desk by saying, “A Desk is an oak desk with a scratch on top,” or explain what a Fish is by saying, “A Fish is a goldfish named Moby,” because both a Desk and a Fish are much more general. The difference between a class and an object parallels the difference between abstract and concrete. An object is an instantiation of a class, or one tangible example of a class. Your goldfish, my guppy, and the zoo’s shark each constitute one instantiation of the Fish class. The concept of a class is useful because of its reusability. Objects gain their attributes from their classes, and all objects have predictable attributes because they are members of certain classes. For example, if you are invited to a graduation party, you automatically know many things about it. You assume there will be a starting time, a certain number of guests, and some quantity of food. You understand what a party object entails because of your previous knowledge of the Party class. You don’t know the number of guests or what food will be served at this particular party, but you understand that because all parties have guests and refreshments, this one must too. Because you understand the general characteristics of a Party, you anticipate different attributes than if you plan to attend a TheaterPerformance object or a DentalAppointment object. In addition to their attributes, objects have methods associated with them, and every object that is an instance of a class is assumed to possess the same methods. For example, for all Party objects, a date and time are set at some point. In a program, you might name these methods setDate() and setTime(). Party guests need to know the date and time and might use methods named getDate() and getTime() to find out the date and time of any Party object. Method names that begin with get and set are very typical. You will learn more about get and set methods in the next section. Your graduation party, then, might have the identifier myGraduationParty. As a member of the Party class, myGraduationParty, like all Party objects, might have data methods setDate() and setTime(). When you use them, the setDate() and setTime() methods require arguments, or information passed to them. For example, statements such as myGraduationParty.setDate("May 12") and myGraduationParty.setTime("6 P.M.") invoke methods that are available for the myGraduationParty object. When you use an object and its methods, think of being able to send a message to the object to direct it to accomplish some task—you can tell the Party object named myGraduationParty to set the date and time you request. Even though yourAnniversaryParty is also a member of the Party class, and even though it also has access to setDate() and setTime() methods, the arguments you send to yourAnniversaryParty methods will be different from those you send to myGraduationParty methods. Within any object-oriented program, you are continuously making requests to objects’ methods and often including arguments as part of those requests. In addition, some methods used in an application must return a message or value. If one of your party guests uses the getDate() method, the guest hopes that the method will respond with the desired information. Similarly, within object-oriented programs, methods are often called upon to return a piece of information to the source of the request. For example, a method within a Payroll class that calculates federal withholding tax might return a tax amount in dollars and cents, and a method within an Inventory class might return true or false, depending on the method’s determination of whether an item is at the reorder point. With object-oriented programming, sometimes you create classes so that you can instantiate objects from them, and other times you create classes to run as applications. Application classes frequently instantiate objects that use the objects of other classes (and their data and methods). Sometimes you write classes that do both. The same programmer does not need to write every class he or she uses. Often, you will write programs that use classes created by others. For example, many programs you have seen so far in this book have used the System class. You did not have to create it or its println() method; both were provided for you by Java’s creators. Similarly, you might create a class that others will use to instantiate objects within their own applications. You can call an application or class that instantiates objects of another class a class client or class user.
  6. Creating a Class

    When you create a class, you must assign a name to the class, and you must determine what data and methods will be part of the class. Suppose you decide to create a class named Employee. One instance variable of Employee might be an employee number, and two necessary methods might be a method to set (or provide a value for) the employee number and another method to get (or retrieve) that employee number. To begin, you create a class header with three parts: • An optional access specifier • The keyword class • Any legal identifier you choose for the name of your class—starting with an uppercase letter is conventional For example, a header for a class that represents an employee might be: public class Employee The most liberal form of access is public. The keyword public is a class modifier. Classes that are public are accessible by all objects. Public classes also can be extended, or used as a basis for any other class. Making access public means that if you develop a good Employee class, and someday you want to develop two classes that are more specific, SalariedEmployee and HourlyEmployee, then you do not have to start from scratch. Each new class can become an extension of the original Employee class, inheriting its data and methods. Although other specifiers exist, you will use the public specifier for most of your classes. After writing the class header public class Employee, you write the body of the Employee class between a set of curly braces. The body contains the data and methods for the class. The data components of a class are often referred to as data fields to help distinguish them from other variables you might use. Figure shows an Employee class that contains one data field named empNum. Data fields are variables you declare within a class but outside of any method. public class Employee { private int empNum; } In Figure, the data field empNum is not preceded by the keyword static. If the keyword static had been inserted there, only one empNum value would be shared by all Employee objects that are eventually instantiated. Because the empNum field in Figure is not preceded by static, when you eventually create, or instantiate, objects from the class, each Employee can have its own unique empNum. Each object gets its own copy of each nonstatic data field in its class. A nonstatic field like empNum is an instance variable for the class because one copy exists for each object instantiation. You already have learned that the access specifier for most Java methods is public. However, most fields, such as empNum in the Employee class, are private, which provides the highest level of security. Assigning private access to a field means that no other classes can access the field’s values, and only methods of the same class are allowed to set, get, or otherwise use private variables. The principle used in creating private access is sometimes called information hiding and is an important component of object-oriented programs. A class’s private data can be changed or manipulated only by a class’s own methods and not by methods that belong to other classes. In contrast to fields, which are usually private, most class methods are public. The resulting private data/public method arrangement provides a means for you to control outside access to your data—only a class’s nonprivate methods can be used to access a class’s private data. The situation is similar to hiring a public receptionist to sit in front of your private office and control which messages you receive (perhaps deflecting trivial or hostile ones) and which messages you send (perhaps checking your spelling, grammar, and any legal implications). The way in which the nonprivate methods are written controls how you use the private data.
  7. Creating Instance Methods in a Class

    Besides data, classes contain methods. For example, one method you need for an Employee class that contains an empNum is the method to retrieve (or return) any Employee’s empNum for use by another class. A reasonable name for this method is getEmpNum(), and its declaration is public int getEmpNum() because it will have public access, return an integer (the employee number), and possess the identifier getEmpNum(). Similarly, you need a method with which to set the empNum field. A reasonable name for this method is setEmpNum(), and its declaration is public void setEmpNum(int emp) because it will have public access, return nothing, possess the identifier setEmpNum(), and require a parameter that represents the employee’s ID number, which is type int. Methods that set or change field values are called mutator methods; methods that retrieve values are called accessor methods. In Java, mutator methods are often called setters, and they conventionally start with the prefix set. Accessor methods are called getters, and they conventionally start with the prefix get. Using these three-letter prefixes with your method names is not required, but it is conventional. Figure shows the get and set methods for the empNum field for the Employee class. public void setEmpNum(int emp) { empNum = emp; } public int getEmpNum() { return empNum; } Notice that, unlike the methods you created earlier in this chapter, the getEmpNum() and setEmpNum() methods do not employ the static modifier. The keyword static is used for classwide methods, but not for methods that “belong” to objects. If you are creating a program with a main() method that you will execute to perform some task, many of your methods will be static so you can call them from within main() without creating objects. However, if you are creating a class from which objects will be instantiated, most methods probably will be nonstatic because you will associate the methods with individual objects. For example, the getEmpNum() method must be nonstatic because it returns a different empNum value for every Employee object you ever create. Nonstatic methods, those methods used with object instantiations, are called instance methods. You can use either a static or nonstatic method with an object, but only nonstatic methods behave uniquely for each object. You cannot use a nonstatic method without an object. Understanding when to declare fields and methods as static and nonstatic is a challenge for new programmers. To help you determine whether a data field should be static, you can ask yourself how many times it occurs. If it occurs once per class, it is static, but if it occurs once per object, it is not static. Table provides a summary.
    In Java, static is a keyword. It also can be used as an adjective.There is no keyword for nonstatic items. When you do not explicitly declare a field or method to be static, it is nonstatic by default.
    Static fields in a class are called class fields.Nonstatic fields in a class are called instance variables.
    Static methods in a class are called class methods. Nonstatic methods in a class are called instance methods.
    When you use a static field or method, you do not need to use an object; for example: JOptionPane.showDialog(); When you use a nonstatic field or method, you must use an object; for example: System.out.println();
    When you create a class with a static field and instantiate 100 objects, only one copy of that field exists in memory. When you create a class with a nonstatic field and instantiate 100 objects, then 100 copies of that field exist in memory.
    When you create a static method in a class and instantiate 100 objects, only one copy of the method exists in memory and the method does not receive a this reference. When you create a nonstatic method in a class and instantiate 100 objects, only one copy of the method exists in memory, but the method receives a this reference that contains the address of the object currently using it.
    Static class variables are not instance variables. The system allocates memory to hold class variables once per class, no matter how many instances of the class you instantiate. The system allocates memory for class variables the first time it encounters a class, and every instance of a class shares the same copy of any static class variables. Instance fields and methods are nonstatic. The system allocates a separate memory location for each nonstatic field in each instance.
    Figure provides examples of how public, private, static, and nonstatic class members can be used by another class. The figure shows a class named MyClass that contains four methods that are public static, private static, public nonstatic, and private nonstatic. The figure also shows a TestClass that instantiates a MyClass object. public class MyClass { public static pubStatMethod() private static privStatMethod() public pubNonstatMethod() private privNonstatMethod() } public class TestClass { MyClass object = new MyClass(); object.pubNonstatMethod(); // The public nonstatic method can be used from TestClass with a MyClass object. object.pubStatMethod(); // The public static method can be used from TestClass with or without anobject. MyClass.pubStatMethod(); // None of the following work MyClass.privStatMethod(); // TestClass doesn’t have access to the private method. MyClass.pubNonstatMethod(); // The nonstatic method must be used with a MyClass object. object.privStatMethod(); // An object can use a static or nonstatic method, but these methods are private and cannot be used here. object.privNonstatMethod(); MyClass.privNonstatMethod(); // This is wrong on two counts—the method is nonstatic, so it needs an object, and in any event, the method is private. } Figure shows a typical class that would be used to declare an Employee class containing one private data field and two public methods, all of which are nonstatic. This class becomes the model for a new data type named Employee; when Employee objects eventually are created, each will have its own empNum field, and each will have access to two methods—one that provides a value for its empNum field and another that retrieves the value stored there. public class Employee { private int empNum; public int getEmpNum() { return empNum; } public void setEmpNum(int emp) { empNum = emp; } }
    Organizing Classes
    Most classes that you create have multiple data fields and methods. For example, in addition to requiring an employee number, an Employee needs a last name, a first name, and a salary, as well as methods to set and get those fields. Figure shows one way you could arrange the data fields for the Employee class. public class Employee { private int empNum; private String empLastName; private String empFirstName; private double empSalary; //Methods will go here } Although there is no requirement to do so, most programmers place data fields in some logical order at the beginning of a class. For example, empNum is most likely used as a unique identifier for each employee (what database users often call a primary key), so it makes sense to list the employee number first in the class. An employee’s last name and first name “go together,” so it makes sense to store these two Employee components adjacently. Despite these commonsense rules, you have a lot of flexibility in how you position your data fields within any class. Because the current Employee class has two String components, they might be declared within the same statement, such as the following: private String empLastName, empFirstName; However, it is usually easier to identify each Employee field at a glance if the fields are listed vertically. You can place a class’s data fields and methods in any order within a class. For example, you could place all the methods first, followed by all the data fields, or you could organize the class so that several data fields are followed by methods that use them, and then several more data fields are followed by the methods that use them. This book follows the convention of placing all data fields first so that you can see their names and data types before reading the methods that use them. The Employee class started in Figure contains only four fields. Even if only one set method and one get method are needed for each, eight methods are required. Consider an employee record for most organizations, and you will realize that many more fields often are required (such as address, phone number, hire date, number of dependents, and so on), as well as many more methods. Finding your way through the list can become a formidable task. For ease in locating class methods, many programmers store them in alphabetical order. Other programmers arrange values in pairs of get and set methods, an order that also results in functional groupings. Figure 3-25 shows how the complete class definition for an Employee might appear.
    public class Employee { private int empNum; private String empLastName; private String empFirstName; private double empSalary; public int getEmpNum() { return empNum; } public void setEmpNum(int emp) { empNum = emp; } public String getEmpLastName() { return empLastName; } public void setEmpLastName(String name) { empLastName = name; } public String getEmpFirstName() { return empFirstName; } public void setEmpFirstName(String name) { empFirstName = name; } public double getEmpSalary() { return empSalary; } public void setEmpSalary(double sal) { empSalary = sal; } }
  8. Declaring Objects and Using Their Methods

    Declaring a class does not create any actual objects. A class is just an abstract description of what an object will be like if any objects are ever actually instantiated. Just as you might understand all the characteristics of an item you intend to manufacture long before the first item rolls off the assembly line, you can create a class with fields and methods long before you instantiate any objects that are members of that class. A two-step process creates an object that is an instance of a class. First, you supply a type and an identifier—just as when you declare any variable—and then you allocate computer memory for that object. For example, you might declare an integer as int someValue; and you might declare an Employee as follows: Employee someEmployee; In this statement, someEmployee can be any legal identifier, but objects conventionally start with a lowercase letter. When you declare an integer as int someValue;, you notify the compiler that an integer named someValue will exist, and you reserve computer memory for it at the same time. When you declare the someEmployee instance of the Employee class, you are notifying the compiler that you will use the identifier someEmployee. However, you are not yet setting aside computer memory in which the Employee named someEmployee might be stored— that is done automatically only for primitive type variables. To allocate the needed memory for an object, you must use the new operator. Two statements that actually complete the process by setting aside enough memory to hold an Employee are as follows: Employee someEmployee; someEmployee = new Employee(); In this statement, Employee is the object’s type (as well as its class), and someEmployee is the name of the object. Also, someEmployee becomes a reference to the object—the name for a memory address where the object is held. Every object name is also a reference—that is, a computer memory location. In Chapter 2, you learned that a class such as Employee is a reference type. The equal sign is the assignment operator, so a value is being assigned to someEmployee in the declaration. The new operator is allocating a new, unused portion of computer memory for someEmployee. The value that the statement is assigning to someEmployee is a memory address at which someEmployee is to be located. You do not need to be concerned with what the actual memory address is—when you refer to someEmployee, the compiler locates it at the appropriate address for you. The final portion of the statement after the new operator, Employee(), with its parentheses, looks suspiciously like a method name. In fact, it is the name of a method that constructs an Employee object. The Employee() method is a constructor, a special type of method that creates and initializes objects. You can write your own constructor for a class, and you will learn how later in this chapter. However, when you don’t write a constructor for a class, Java writes one for you. Whether you write your own constructor or use the one automatically created by Java, the name of the constructor is always the same as the name of the class whose objects it constructs. After an object has been instantiated, its methods can be accessed using the object’s identifier, a dot, and a method call. For example, Figure shows an application that instantiates two Employee objects. The two objects, clerk and driver, each use the setEmpNum() and getEmpNum() method one time. The DeclareTwoEmployees application can use these methods because they are public, and it must use each of them with an Employee object because the methods are not static.
    public class DeclareTwoEmployees { public static void main(String[] args) { Employee clerk = new Employee(); Employee driver = new Employee(); clerk.setEmpNum(345); driver.setEmpNum(567); System.out.println("The clerk's number is " + clerk.getEmpNum() + " and the driver's number is " + driver.getEmpNum()); } }
    Understanding Data Hiding
    Within the DeclareTwoEmployees class, you must use the public methods setEmpNum() and getEmpNum() to be able to set and retrieve the value of the empNum field for each Employee because you cannot access the private empNum field directly. For example, the following statement would not be allowed: clerk.empNum = 789; This statement generates the error message empNum has private access in Employee, meaning you cannot access empNum from the DeclareTwoEmployees class. If you made empNum public instead of private, a direct assignment statement would work, but you would violate an important principle of object-oriented programming—that of data hiding using encapsulation. Data fields usually should be private, and a client application should be able to access them only through the public interfaces—that is, through the class’s public methods. However, you might reasonably ask, “When I write an application, if I can’t set an object’s data field directly, but I can set it using a public method, what’s the difference? The field value is set either way!” Actually, the setEmpNum() method in the Employee class does accept any integer value you send into it. However, you could rewrite the setEmpNum() method to prevent invalid data from being assigned to an object’s data fields. For example, perhaps your organization has rules for valid employee ID numbers—they must be no fewer than five digits, or they must start with a 9, for instance. The statements that enforce these requirements would be part of the setEmpNum() method. Checking a value for validity requires decision making. You will learn more in the chapter “Making Decisions.” Similarly, a get method might control how a value is retrieved. Perhaps you do not want clients to have access to part of an employee’s ID number, or perhaps you always want to add a company code to every ID before it is returned to the client. Even when a field has no data value requirements or restrictions, making data private and providing public set and get methods establishes a framework that makes such modifications easier in the future. You will not necessarily write set and get methods for every field in a class; there are some fields that clients will not be allowed to alter. Some fields will simply be assigned values, and some field values might not be set directly, but might be calculated from the values of others.
  9. An Introduction to Using Constructors

    When you create a class, such as Employee, and instantiate an object with a statement such as the following, you actually are calling the Employee class constructor that is provided by default by the Java compiler: Employee chauffeur = new Employee(); A constructor establishes an object; a default constructor is one that requires no arguments. A default constructor is created automatically by the Java compiler for any class you create whenever you do not write your own constructor. When the prewritten, default constructor for the Employee class is called, it establishes one Employee object with the identifier provided. The automatically supplied default constructor provides the following specific initial values to an object’s data fields: • Numeric fields are set to 0 (zero). • Character fields are set to Unicode ‘\u0000’. • Boolean fields are set to false. • Fields that are object references (for example, String fields) are set to null (or empty). If you do not want each field in an object to hold these default values, or if you want to perform additional tasks when you create an instance of a class, you can write your own constructor. Any constructor you write must have the same name as the class it constructs, and constructors cannot have a return type—not even void. Normally, you declare constructors to be public so that other classes can instantiate objects that belong to the class. When you write a constructor for a class, you no longer have access to the automatically created version. For example, if you want every Employee object to have a default starting salary of $300.00 per week, you could write the constructor for the Employee class that appears in Figure 3-29. Any Employee object instantiated will have an empSalary field value equal to 300.00, and the other Employee data fields will contain the automatically supplied default values. Even though you might want a field to hold the default value for its data type, you still might prefer to explicitly initialize the field for clarity. public Employee() { empSalary = 300.00; } You can write any Java statement in a constructor. Although you usually have no reason to do so, you could display a message from within a constructor or perform any other task. You can place the constructor anywhere inside the class, outside of any other method. Typically, a constructor is placed with the other methods. Often, programmers list the constructor first because it is the first method used when an object is created. You never are required to write a constructor for a class to make a class that compiles without error; Java provides you with a default version if the class contains no explicit constructor.
  10. Understanding that Classes Are Data Types

    The classes that you create become data types. Programmers sometimes refer to classes as abstract data types, or ADTs. An abstract data type is a type whose implementation is hidden and accessed through its public methods. A class that you create also can be called a programmer-defined data type; in other words, it is a type that is not built into the language. A class is a composite type—that is, a class is composed from smaller parts. Java’s primitive types are not composite. Java has eight built-in primitive data types such as int and double. Primitive types can also be called scalar types. You do not have to define these simple types; the creators of Java already have done so. For example, when the int type was first created, the programmers who designed it had to think about the following: Q: What shall we call it? A: int. Q: What are its attributes? A: An int is stored in four bytes; it holds whole-number values. Q: What methods are needed by int? A: A method to assign a value to a variable (for example, an int’s value might be 32). Q: Any other methods? A: Some operators to perform arithmetic with variables. Q: Any other methods? A: Of course, there are even more attributes and methods of an int, but these are a good start. Your job in constructing a new data type is similar. If you need a class for employees, you should ask: Q: What shall we call it? A: Employee. Q: What are its attributes? A: It has an integer ID number, a String last name, and a double salary. Q: What methods are needed by Employee? A: A method to assign values to the data fields of an instance of this class. Q: Any other methods? A: A method to display data in an instance of this class. Q: Any other methods? A: Probably, but this is enough to get started. When you declare a primitive type object, you provide its type and an identifier. When you declare an object from one of your classes, you do the same. After each exists, you can use them in similar ways. For example, suppose you declare an int named myInt and an Employee named myEmployee. Then each can be passed into a method, returned from a method, or assigned to another object of the same data type. One example, shows a program in which the main() method uses two other methods. One method accepts an Employee as a parameter, and the other returns an Employee. (The Employee class is defined in Figure.)
    import java.util.Scanner; class MethodsThatUseAnEmployee { public static void main (String args[]) { Employee myEmployee; // Employee is declared. myEmployee = getEmployeeData(); // Value returned from getEmployeeData() method is assigned to myEmployee object. displayEmployee(myEmployee); // myEmployee object is passed to displayEmployee() method. } public static Employee getEmployeeData() // Return type is Employee. { Employee tempEmp = new Employee(); int id; double sal; Scanner input = new Scanner(System.in); System.out.print("Enter employee ID >> "); id = input.nextInt(); tempEmp.setEmpNum(id); System.out.print("Enter employee salary >> "); sal = input.nextDouble(); tempEmp.setEmpSalary(sal); return tempEmp; // Employee object is returned. } public static void displayEmployee(Employee anEmp) // Parameter is Employee type. { System.out.println("\nEmployee #" + anEmp.getEmpNum() + " Salary is " + anEmp.getEmpSalary()); } }
  11. You Do It Exercises

    public class ParadiseInfo { public static void main(String[] args) { displayInfo(); } public static void displayInfo() { System.out.println("Paradise Day Spa wants to pamper you."); System.out.println("We will make you look good."); } }
    public class TestInfo { public static void main(String[] args) { System.out.println("Calling method from another class:"); ParadiseInfo.displayInfo(); } }
    import java.util.Scanner; public class ParadiseInfo2 { public static void main(String[] args) { double price; double discount; double savings; Scanner keyboard = new Scanner(System.in); System.out.print("Enter cutoff price for discount >> "); price = keyboard.nextDouble(); System.out.print("Enter discount rate as a whole number >> "); discount = keyboard.nextDouble(); displayInfo(); savings = computeDiscountInfo(price, discount); System.out.println("Special this week on any service over " + price); System.out.println("Discount of " + discount + " percent"); System.out.println("That's a savings of at least $" + savings); } public static void displayInfo() { System.out.println("Paradise Day Spa wants to pamper you."); System.out.println("We will make you look good."); } public static double computeDiscountInfo(double price, double discountRate) { double savings; savings = price * discountRate / 100; return savings; } }
    public class SpaService { private String serviceDescription; private double price; public SpaService() { serviceDescription = "XXX"; price = 0; } public void setServiceDescription(String service) { serviceDescription = service; } public void setPrice(double servicePrice) { price = servicePrice; } public String getServiceDescription() { return serviceDescription; } public double getPrice() { return price; } }
    import java.util.Scanner; public class CreateSpaServices { public static void main(String[] args) { SpaService firstService = new SpaService(); SpaService secondService = new SpaService(); firstService = getData(firstService); secondService = getData(secondService); System.out.println("First service details:"); System.out.println(firstService.getServiceDescription() + " $" + firstService.getPrice()); System.out.println("Second service details:"); System.out.println(secondService.getServiceDescription() + " $" + secondService.getPrice()); } public static SpaService getData(SpaService service) { String serviceDescription; double price; Scanner keyboard = new Scanner(System.in); System.out.print("Enter service >> "); serviceDescription = keyboard.nextLine(); System.out.print("Enter price >> "); price = keyboard.nextDouble(); keyboard.nextLine(); service.setServiceDescription(serviceDescription); service.setPrice(price); return service; } }
  12. Case Problems

    import java.util.Scanner; public class CarlysEventPriceWithMethods { public static void main(String[] args) { int guests; guests = getGuests(); displayMotto(); displayDetails(guests); } public static int getGuests() { int guests; Scanner input = new Scanner(System.in); System.out.print("Enter number of guests >> "); guests = input.nextInt(); return guests; } public static void displayDetails(int guests) { final double GUEST_PRICE = 35.00; final int LARGE_EVENT = 50; double price; price = guests * GUEST_PRICE; System.out.println("The price for an event with " + guests + " guests at $" + GUEST_PRICE + " per guest is $" + price); System.out.println("Whether this is a large event is " + (guests >= LARGE_EVENT)); } public static void displayMotto() { System.out.println("****************************************************"); System.out.println("* *"); System.out.println("* Carly's makes the food that makes it a party. *"); System.out.println("* *"); System.out.println("****************************************************"); } }
    class Event { public final static double GUEST_PRICE = 35.00; public final static int LARGE_EVENT = 50; private String eventNumber; private int guests; private double price; public void setEventNumber(String num) { eventNumber = num; } public void setGuests(int gsts) { guests = gsts; price = guests * GUEST_PRICE; } public String getEventNumber() { return eventNumber; } public int getGuests() { return guests; } public double getPrice() { return price; } }
    import java.util.Scanner; public class EventDemo { public static void main(String[] args) { String eventNum; int guests; Event e = new Event(); eventNum = getEventNumber(); guests = getGuests(); e.setEventNumber(eventNum); e.setGuests(guests); CarlysEventPriceWithMethods.displayMotto(); displayDetails(e); } public static String getEventNumber() { String num; Scanner input = new Scanner(System.in); System.out.print("Enter event number >> "); num = input.nextLine(); return num; } public static int getGuests() { int guests; Scanner input = new Scanner(System.in); System.out.print("Enter number of guests >> "); guests = input.nextInt(); input.nextLine(); return guests; } public static void displayDetails(Event e) { System.out.println("\nEvent #" + e.getEventNumber()); System.out.println("The price for an event with " + e.getGuests() + " guests at $" + e.GUEST_PRICE + " per guest is $" + e.getPrice()); System.out.println("Whether this is a large event is " + (e.getGuests() >= e.LARGE_EVENT)); } }
    import java.util.Scanner; public class SammysRentalPriceWithMethods { public static void main(String[] args) { int minutes; minutes = getMinutes(); RentalDemo.displayMotto(); displayDetails(minutes); } public static int getMinutes() { int minutes; Scanner input = new Scanner(System.in); System.out.print("Enter minutes >> "); minutes = input.nextInt(); return minutes; } public static void displayDetails(int minutes) { final int MINUTES_IN_HOUR = 60; final int HOUR_RATE = 40; int hours; int extraMinutes; int price; hours = minutes / MINUTES_IN_HOUR; extraMinutes = minutes % MINUTES_IN_HOUR; price = hours * HOUR_RATE + extraMinutes; System.out.println("For a rental of " + hours + " hours and " + extraMinutes + " minutes, the price is $" + price); } }
    class Rental { public final int MINUTES_IN_HOUR = 60; public final int HOUR_RATE = 40; private String contractNumber; private int hours; private int extraMinutes; private double price; public void setContractNumber(String num) { contractNumber = num; } public void setHoursAndMinutes(int minutes) { hours = minutes / MINUTES_IN_HOUR; extraMinutes = minutes % MINUTES_IN_HOUR; price = hours * HOUR_RATE + extraMinutes; } public String getContractNumber() { return contractNumber; } public int getHours() { return hours; } public int getExtraMinutes() { return extraMinutes; } public double getPrice() { return price; } }
    import java.util.Scanner; public class RentalDemo { public static void main(String[] args) { String contractNum; int minutes; Rental r = new Rental(); contractNum = getContractNumber(); minutes = getMinutes(); r.setContractNumber(contractNum); r.setHoursAndMinutes(minutes); displayDetails(r); } public static String getContractNumber() { String num; Scanner input = new Scanner(System.in); System.out.print("Enter contract number >> "); num = input.nextLine(); return num; } public static int getMinutes() { int minutes; Scanner input = new Scanner(System.in); System.out.print("Enter minutes >> "); minutes = input.nextInt(); return minutes; } public static void displayDetails(Rental r) { System.out.println("\nContract #" + r.getContractNumber()); System.out.println("For a rental of " + r.getHours() + " hours and " + r.getExtraMinutes() + " minutes, at a rate of " + r.HOUR_RATE + " the price is $" + r.getPrice()); } public static void displayMotto() { System.out.println("SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS"); System.out.println("S S"); System.out.println("S Sammy's makes it fun in the sun. S"); System.out.println("S S"); System.out.println("SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS"); } }