The document provides an in-depth exploration of classes and objects in programming, focusing on concepts such as constructors, access control, and exception handling. It includes a case study on a Time class, discussing its implementation, methods, and the importance of encapsulation. Additionally, it covers advanced topics like composition, enum types, and the use of access modifiers to manage class member visibility.
The document provides an in-depth exploration of classes and objects in programming, focusing on concepts such as constructors, access control, and exception handling. It includes a case study on a Time class, discussing its implementation, methods, and the importance of encapsulation. Additionally, it covers advanced topics like composition, enum types, and the use of access modifiers to manage class member visibility.
8.2 Time Class Case Study Class Time1 represents the time of day. private int instance variables hour, minute and second represent the time in universal-time format (24-hour clock format in which hours are in the range 0–23, and minutes and seconds are each in the range 0–59). public methods setTime, toUniversalString and toString. ◦ Clled the public services or the public interface that the class provides to its clients.
8.2 Time Class Case Study (Cont.) Method setTime and Throwing Exceptions Method setTime declares three int parameters and uses them to set the time. Lines 13–14 test each argument to determine whether the value is outside the proper range.
8.2 Time Class Case Study (Cont.) Method setTime and Throwing Exceptions (cont.) For incorrect values, setTime throws an exception of type IllegalArgumentException ◦ Notifies the client code that an invalid argument was passed to the method. ◦ Can use try...catch to catch exceptions and attempt to recover from them. ◦ The class instance creation expression in the throw statement creates a new object of type IllegalArgumentException. In this case, we call the constructor that allows us to specify a custom error message. ◦ After the exception object is created, the throw statement immediately terminates method setTime and the exception is returned to the calling method that attempted to set the time.
8.2 Time Class Case Study (Cont.) Software Engineering of the Time1 Class Declaration The instance variables hour, minute and second are each declared private. The actual data representation used within the class is of no concern to the class’s clients. Reasonable for Time1 to represent the time internally as the number of seconds since midnight or the number of minutes and seconds since midnight. Clients could use the same public methods and get the same results without being aware of this.
8.3 Controlling Access to Members Access modifiers public and private control access to a class’s variables and methods. ◦ Chapter 9 introduces access modifier protected. public methods present to the class’s clients a view of the services the class provides (the class’s public interface). Clients need not be concerned with how the class accomplishes its tasks. ◦ For this reason, the class’s private variables and private methods (i.e., its implementation details) are not accessible to its clients. private class members are not accessible outside the class.
8.4 Referring to the Current Object’s Members with the this Reference (Cont.) When you compile a .java file containing more than one class, the compiler produces a separate class file with the .class extension for every compiled class. When one source-code (.java) file contains multiple class declarations, the compiler places both class files for those classes in the same directory. A source-code file can contain only one public class—otherwise, a compilation error occurs. Non-public classes can be used only by other classes in the same package.
8.5 Time Class Case Study: Overloaded Constructors (Cont.)
Class Time2 (Fig. 8.5) contains five overloaded constructors that
provide convenient ways to initialize objects. The compiler invokes the appropriate constructor by matching the number, types and order of the types of the arguments specified in the constructor call with the number, types and order of the types of the parameters specified in each constructor declaration.
8.5 Time Class Case Study: Overloaded Constructors (Cont.)
Using this as shown here is a popular way to reuse initialization code
provided by another of the class’s constructors A constructor that calls another constructor in this manner is known as a delegating constructor Makes the class easier to maintain and modify ◦ If we need to change how objects of class Time2 are initialized, only the constructor that the class’s other constructors call will need to be modified
A program can declare a so-called no-argument constructor that is invoked
without arguments. Such a constructor simply initializes the object as specified in the constructor’s body. Using this in method-call syntax as the first statement in a constructor’s body invokes another constructor of the same class. ◦ Popular way to reuse initialization code provided by another of the class’s constructors rather than defining similar code in the no-argument constructor’s body. Once you declare any constructors in a class, the compiler will not provide a default constructor.
8.5 Time Class Case Study: Overloaded Constructors (Cont.) Notes Regarding Class Time2’s set and get Methods and Constructors Methods can access a class’s private data directly without calling the get methods. However, consider changing the representation of the time from three int values (requiring 12 bytes of memory) to a single int value representing the total number of seconds that have elapsed since midnight (requiring only four bytes of memory). ◦ If we made such a change, only the bodies of the methods that access the private data directly would need to change—in particular, the three-argument constructor, the setTime method and the individual set and get methods for the hour, minute and second. ◦ There would be no need to modify the bodies of methods toUniversalString or toString because they do not access the data directly.
8.5 Time Class Case Study: Overloaded Constructors (Cont.) Designing the class in this manner reduces the likelihood of programming errors when altering the class’s implementation. Similarly, each Time2 constructor could be written to include a copy of the appropriate statements from the three-argument constructor. ◦ Doing so may be slightly more efficient, because the extra constructor calls are eliminated. ◦ But, duplicating statements makes changing the class’s internal data representation more difficult. ◦ Having the Time2 constructors call the constructor with three arguments requires any changes to the implementation of the three-argument constructor be made only once.
8.6 Default and No-Argument Constructors Every class must have at least one constructor. If you do not provide any constructors in a class’s declaration, the compiler creates a default constructor that takes no arguments when it’s invoked. The default constructor initializes the instance variables to the initial values specified in their declarations or to their default values (zero for primitive numeric types, false for boolean values and null for references). Recall that if your class declares constructors, the compiler will not create a default constructor. ◦ In this case, you must declare a no-argument constructor if default initialization is required. ◦ Like a default constructor, a no-argument constructor is invoked with empty parentheses.
8.7 Notes on Set and Get Methods (Cont.) It would seem that providing set and get capabilities is essentially the same as making a class’s instance variables public. ◦ A public instance variable can be read or written by any method that has a reference to an object that contains that variable. ◦ If an instance variable is declared private, a public get method certainly allows other methods to access it, but the get method can control how the client can access it. ◦ A public set method can—and should—carefully scrutinize at-tempts to modify the variable’s value to ensure valid values. Although set and get methods provide access to private data, it is restricted by the implementation of the methods.
8.9 Enum Types (Cont.) Each enum declaration declares an enum class with the following restrictions: ◦ enum constants are implicitly final. ◦ enum constants are implicitly static. ◦ Any attempt to create an object of an enum type with operator new results in a compilation error. enum constants can be used anywhere constants can be used, such as in the case labels of switch statements and to control enhanced for statements.
8.9 Enum Types (Cont.) enum declarations contain two parts—the enum constants and the other members of the enum type. An enum constructor can specify any number of parameters and can be overloaded. For every enum, the compiler generates the static method values that returns an array of the enum’s constants. When an enum constant is converted to a String, the constant’s identifier is used as the String representation.
8.10 Garbage Collection (Cont.) So, memory leaks that are common in other languages like C and C++ (because memory is not automatically reclaimed in those languages) are less likely in Java, but some can still happen in subtle ways. Resource leaks other than memory leaks can also occur. ◦ An app may open a file on disk to modify its contents. ◦ If the app does not close the file, it must terminate before any other app can use the file.
8.10 Garbage Collection (Cont.) A Note about Class Object’s finalize Method Every class in Java has the methods of class Object (package java.lang), one of which is method finalize. You should never use method finalize, because it can cause many problems and there’s uncertainty as to whether it will ever get called before a program terminates. The original intent of finalize was to allow the garbage collector to perform termination housekeeping on an object just before reclaiming the object’s memory.
8.10 Garbage Collection (Cont.) Now, it’s considered better practice for any class that uses system resources—such as files on disk—to provide a method that programmers can call to release resources when they’re no longer needed in a program. AutoClosable objects reduce the likelihood of resource leaks when you use them with the try-with-resources statement. As its name implies, an AutoClosable object is closed automatically, once a try-with-resources statement finishes using the object.
8.12 static Import A static import declaration enables you to import the static members of a class or interface so you can access them via their unqualified names in your class—that is, the class name and a dot (.) are not required when using an imported static member. Two forms ◦ One that imports a particular static member (which is known as single static import) ◦ One that imports all static members of a class (which is known as static import on demand)
8.12 static Import (Cont.) The following syntax imports a particular static member: import static packageName.ClassName.staticMemberName; where packageName is the package of the class, ClassName is the name of the class and staticMemberName is the name of the static field or method. The following syntax imports all static members of a class: import static packageName.ClassName.*; packageName is the package of the class and ClassName is the name of the class. ◦ * indicates that all static members of the specified class should be available for use in the class(es) declared in the file. static import declarations import only static class members. Regular import statements should be used to specify the classes used in a program.
8.13 final Instance Variables (cont.) final variables can be initialized when they are declared or by each of the class’s constructors so that each object of the class has a different value. If a class provides multiple constructors, every one would be required to initialize each final variable. A final variable cannot be modified by assignment after it’s initialized. If a final variable is not initialized, a compilation error occurs.
In earlier chapters, we demonstrated monetary calculations using values of type
double. ◦ some double values are represented approximately. Any application that requires precise floating-point calculations—such as those in financial applications—should instead use class BigDecimal (from package java.math).
8.15 Using BigDecimal for Precise Monetary Calculations (Cont.) Rounding BigDecimal Values In addition to precise calculations, BigDecimal also gives you control over how values are rounded—by default all calculations are exact and no rounding occurs. If you do not specify how to round BigDecimal values and a given value cannot be represented exactly—such as the result of 1 divided by 3, which is 0.3333333…—an ArithmeticException occurs. You can specify the rounding mode for BigDecimal by supplying a MathContext object (package java.math) to class BigDecimal’s constructor when you create a BigDecimal. You may also provide a MathContext to various BigDecimal methods that perform calculations.
8.15 Using BigDecimal for Precise Monetary Calculations (Cont.) Class MathContext contains several pre-configured MathContext objects that you can learn about at ◦ http://docs.oracle.com/javase/7/docs/api/java/ math/MathContext.html By default, each pre-configured MathContext uses so called “bankers rounding” as explained for the RoundingMode constant HALF_EVEN at: ◦ http://docs.oracle.com/javase/7/docs/api/java/ math/RoundingMode.html#HALF_EVEN
8.15 Using BigDecimal for Precise Monetary Calculations (Cont.) Scaling BigDecimal Values A BigDecimal’s scale is the number of digits to the right of its decimal point. If you need a BigDecimal rounded to a specific digit, you can call BigDecimal method setScale. For example, the following expression returns a BigDecimal with two digits to the right of the decimal point and using bankers rounding: ◦ amount.setScale(2, RoundingMode.HALF_EVEN)