CSC245 Lecture 2
CSC245 Lecture 2
A Deeper Look
DIANA HAIDAR 1
Outline
class Time Case Study
this Reference
Overloaded Constructors
Notes on set and get Methods
Composition
Garbage Collection and Method finalize
static class Members
final Instance Variables
Software Reusability
Data Abstraction and Encapsulation
DIANA HAIDAR 2
class Time Case Study
The class has a default constructor that is supplied by the compiler.
Methods that modify the values of private instance variables should verify that the intended new values
are correct (validation). If they are not, the set methods should place the private instance variables into an
appropriate consistent state.
1 // Fig. 8.1: Time1.java
2 // Time1 class declaration maintains the time in 24-hour format.
3
4 public class Time1
5 {
6 private int hour; // 0 – 23
7 private int minute; // 0 - 59
8 private int second; // 0 - 59
9
10 // set a new time value using universal time; ensure that
11 // the data remains consistent by setting invalid values to zero
12 public void setTime( int h, int m, int s )
13
14 hour = ( ( h >= 0 && h < 24 ) ? h : 0 ); // validate hour
15 minute = ( ( m >= 0 && m < 60 ) ? m : 0 ); // validate minute
16 second = ( ( s >= 0 && s < 60 ) ? s : 0 ); // validate second
17 } // end method setTime
18
DIANA HAIDAR 3
class Time Case Study
The public methods setTime, toUniversalString, and toString are also called the public services or the
public interface that the class provides to its clients.
DIANA HAIDAR 4
class Time Case Study
1 // Fig. 8.2: Time1Test.java 18 // change time and output updated time
2 // Time1 object used in an application. 19 time.setTime( 13, 27, 6 );
3 20 System.out.print( "Universal time after setTime is: " );
4 public class Time1Test 21 System.out.println( time.toUniversalString() );
5 { 22 System.out.print( "Standard time after setTime is: " );
6 public static void main( String args[] ) 23 System.out.println( time.toString() );
7 { 24 System.out.println(); // output a blank line
8 // create and initialize a Time1 object 25
9 Time1 time = new Time1(); // invokes Time1 constructor 26 // set time with invalid values; output updated time
10 27 time.setTime( 99, 99, 99 );
11 // output string representations of the time 28 System.out.println( "After attempting invalid settings:" );
12 System.out.print( "The initial universal time is: " ); 29 System.out.print( "Universal time: " );
13 System.out.println( time.toUniversalString() ); 30 System.out.println( time.toUniversalString() );
14 System.out.print( "The initial standard time is: " ); 31 System.out.print( "Standard time: " );
15 System.out.println( time.toString() ); 32 System.out.println( time.toString() );
16 System.out.println(); // output a blank line 33 } // end main
17 34 } // end class Time1Test
DIANA HAIDAR 5
class Time Case Study
Common programming error: 1 // Fig. 8.3: MemberAccessTest.java
2 // Private members of class Time1 are not accessible.
An attempt by a method that is not a 3 public class MemberAccessTest
member of a class to access a private 4 {
member of that class is a compilation 5 public static void main( String args[] )
error. 6 {
7 Time1 time = new Time1(); // create and initialize Time1 object
8
9 time.hour = 7; // error: hour has private access in Time1
10 time.minute = 15; // error: minute has private access in Time1
11 time.second = 30; // error: second has private access in Time1
12 } // end main
13 } // end class MemberAccessTest
DIANA HAIDAR 6
this Reference
If a method contains a parameter or a local variable with the same name as an instance variable, that
method will refer to the parameter rather than the instance variable. In this case, the parameter shadows
the instance variable in the method's scope.
Error-prevention (logic error): Avoid method parameter names or local variable names that conflict with
instance variable names. This helps to prevent subtle, hard-to-locate bugs.
To distinguish between (parameters or local variables) and instance variables, use the keyword this .
Any object can access a reference to itself with keyword this.
DIANA HAIDAR 7
this Reference 1
2
// Fig. 8.4: ThisTest.java
// this used implicitly and explicitly to refer to members of an object.
3
4 public class ThisTest
A source-code (.java) file can contain 5 {
multiple class declarations, but the 6 public static void main( String args[] )
compiler produces a separate .class 7 {
file for each compiled class. 8 SimpleTime time = new SimpleTime( 15, 30, 19 );
9 System.out.println( time.buildString() );
A source-code file can contain only 10 } // end main
one public class, otherwise a 11 } // end class ThisTest
12
compilation error occurs.
13 // class SimpleTime demonstrates the "this" reference
14 class SimpleTime
15 {
16 private int hour; // 0-23
17 private int minute; // 0-59
18 private int second; // 0-59
19
20 // if the constructor uses parameter names identical to
21 // instance variable names the "this" reference is
22 // required to distinguish between names
23 public SimpleTime( int hour, int minute, int second )
24 {
25 this.hour = hour; // set "this" object's hour
26 this.minute = minute; // set "this" object's minute
27 this.second = second; // set "this" object's second
28 } // end SimpleTime constructor
29
DIANA HAIDAR 8
this Reference
// use explicit and implicit "this" to call toUniversalString
A non-static method implicitly uses 30
31 public String buildString()
this to refer to an object's instance
32 {
variables or methods, nevertheless, the
33 return String.format( "%24s: %s\n%24s: %s",
keyword this can be used explicitly. 34 "this.toUniversalString()", this.toUniversalString(),
35 "toUniversalString()", toUniversalString() );
36 } // end method buildString
Performance tip: Java conserves 37
storage by maintaining only one copy 38 // convert to String in universal-time format (HH:MM:SS)
copy of instance variables, but not the 41 // "this" is not required here to access instance variables,
42 // because method does not have local variables with same
methods. Each method of the class
implicitly uses this to determine the 43 // names as instance variables
44 return String.format( "%02d:%02d:%02d",
specific object of the class to
45 this.hour, this.minute, this.second );
manipulate.
46 } // end method toUniversalString
47 } // end class SimpleTime
this.toUniversalString(): 15:30:19
toUniversalString(): 15:30:19
DIANA HAIDAR 9
Overloaded Constructors
1 // Fig. 8.5: Time2.java
2 // Time2 class declaration with overloaded constructors.
A class can have multiple overloaded 3
constructors with different signatures 4 public class Time2
that enable objects to be initialized in 5 {
6 private int hour; // 0 - 23
different ways.
7 private int minute; // 0 - 59
8 private int second; // 0 - 59
The compiler invokes the appropriate 9
constructor by matching the number 10 // Time2 no-argument constructor: initializes each instance variable
and types of the arguments specified in 11 // to zero; ensures that Time2 objects start in a consistent state
the constructor call with the number 12 public Time2()
13 {
and types of the parameters specified 14 this( 0, 0, 0 ); // invoke Time2 constructor with three arguments
in each constructor declaration. 15 } // end Time2 no-argument constructor
16
17 // Time2 constructor: hour supplied, minute and second defaulted to 0
18 public Time2( int h )
19 {
20 this( h, 0, 0 ); // invoke Time2 constructor with three arguments
21 } // end Time2 one-argument constructor
22
23 // Time2 constructor: hour and minute supplied, second defaulted to 0
24 public Time2( int h, int m )
25 {
26 this( h, m, 0 ); // invoke Time2 constructor with three arguments
27 } // end Time2 two-argument constructor
28
DIANA HAIDAR 10
Overloaded Constructors
Common programming error:
If a class has constructors, but none of the public constructors is a no-argument constructor, a compilation
error occurs when attempting to initialize an object of the class.
A compiler calls a default constructor only if the class does not have any constructors or if the class has a
public no-argument constructor.
DIANA HAIDAR 11
Overloaded Constructors
Common programming error: 29 // Time2 constructor: hour, minute and second supplied
30 public Time2( int h, int m, int s )
The keyword this can be used in a 31 {
constructor's body to call another 32 setTime( h, m, s ); // invoke setTime to validate time
DIANA HAIDAR 12
Overloaded Constructors
52 // validate and set hour 77 // get minute value
53 public void setHour( int h ) 78 public int getMinute()
54 { 79 {
55 hour = ( ( h >= 0 && h < 24 ) ? h : 0 ); 80 return minute;
81 } // end method getMinute
56 } // end method setHour
82
57
83 // get second value
58 // validate and set minute
84 public int getSecond()
59 public void setMinute( int m )
85 {
60 { 86 return second;
61 minute = ( ( m >= 0 && m < 60 ) ? m : 0 ); 87 } // end method getSecond
62 } // end method setMinute 88
63 89 // convert to String in universal-time format (HH:MM:SS)
64 // validate and set second 90 public String toUniversalString()
65 public void setSecond( int s ) 91 {
66 { 92 return String.format(
67 second = ( ( s >= 0 && s < 60 ) ? s : 0 ); 93 "%02d:%02d:%02d", getHour(), getMinute(), getSecond() );
94 } // end method toUniversalString
68 } // end method setSecond
95
69
96 // convert to String in standard-time format (H:MM:SS AM or PM)
70 // Get Methods
97 public String toString()
71 // get hour value
98 {
72 public int getHour()
99 return String.format( "%d:%02d:%02d %s",
73 { 100 ( (getHour() == 0 || getHour() == 12) ? 12 : getHour() % 12 ),
74 return hour; 101 getMinute(), getSecond(), ( getHour() < 12 ? "AM" : "PM" ) );
75 } // end method getHour 102 } // end method toString
76 103 } // end class Time2
DIANA HAIDAR 13
Calling Overloaded Constructors
DIANA HAIDAR 14
Calling Overloaded Constructors
38 System.out.println( "t6: Time2 object t4 specified" );
39 System.out.printf( " %s\n", t6.toUniversalString() );
40 System.out.printf( " %s\n", t6.toString() );
41 } // end main
42 } // end class Time2Test
DIANA HAIDAR 15
Notes on set and get Methods
Predicate methods are accessor methods to test whether a condition is true or false.
Examples of predicate methods: isEmpty method or isFull method for a container class (a data structure
of items, such as a linked list, a stack, or a queue).
A program might test isEmpty before attempting to read another item from a container object.
A program might test isFull before attempting to insert an item into a container object.
Encapsulating a particular task to a method (such as setting the hour in a Time2 object) makes it easier to
debug and maintain a class.
DIANA HAIDAR 16
Composition
One form of software reuse is composition, in which a class has members references to objects of other
class.
Composition is sometimes referred to as has-a relationship.
Example: A class AlarmClock has two references to Time objects, one is current time and the other is
alarming time.
DIANA HAIDAR 17
Composition
1 // Fig. 8.7: Date.java 22 // utility method to confirm proper month value
2 // Date class declaration. 23 private int checkMonth( int testMonth )
3 24 {
4 public class Date 25 if ( testMonth > 0 && testMonth <= 12 ) // validate month
5 { 26 return testMonth;
6 private int month; // 1-12 27 else // month is invalid
DIANA HAIDAR 18
Composition
41 // check if day in range for month
42 if ( testDay > 0 && testDay <= daysPerMonth[ month ] )
43 return testDay;
44
45 // check for leap year
46 if ( month == 2 && testDay == 29 && ( year % 400 == 0 ||
47 ( year % 4 == 0 && year % 100 != 0 ) ) )
48 return testDay;
49
50 System.out.printf( "Invalid day (%d) set to 1.", testDay );
51 return 1; // maintain object in consistent state
52 } // end method checkDay
53
54 // return a String of the form month/day/year
55 public String toString()
56 {
57 return String.format( "%d/%d/%d", month, day, year );
58 } // end method toString
59 } // end class Date
DIANA HAIDAR 19
Composition 1
2
// Fig. 8.8: Employee.java
// Employee class with references to other objects.
3
A class Employee has two references to Date 4 public class Employee
DIANA HAIDAR 20
Composition
A call to this in the class or to object reference outside the class implicitly calls the object's toString
method.
DIANA HAIDAR 21
Garbage Collection and Method finalize
JVM marks an object for garbage collection when there are no more references for an object.
JVM performs automatic garbage collection to reclaim the memory occupied by these objects, so the
memory can be used for other objects.
Every class in Java inherits the methods of class Object (package java.lang), including the finalize method.
finalize is called by the garbage collector to perform termination housekeeping just before the garbage
collector reclaims the object's memory.
finalize does not take parameters and has return type void.
DIANA HAIDAR 22
static class Members 1 // Fig. 8.12: Employee.java
2 // Static variable used to maintain a count of the number of
static instance variables (also known 3 // Employee objects in memory.
as class variables) represent classwide 4
information, such that all objects of the 5 public class Employee
class share the same copy of the static 6 {
class variable. 7 private String firstName;
DIANA HAIDAR 23
static class Members 23 // subtract 1 from static count when garbage
24 // collector calls finalize to clean up object;
25 // confirm that finalize was called
static methods cannot access non-static 26 protected void finalize()
class members, because a static method 27 {
can be called even when no objects of 28 count--; // decrement static count of employees
29 System.out.printf( "Employee finalizer: %s %s; count = %d\n",
the class have been instantiated. 30 firstName, lastName, count );
31 } // end method finalize
Common programming error: Referring 32
to this in a static method is a syntax 33 // get first name
error. 34 public String getFirstName()
35 {
36 return firstName;
37 } // end method getFirstName
38
39 // get last name
40 public String getLastName()
41 {
42 return lastName;
43 } // end method getLastName
44
45 // static method to get static count value
46 public static int getCount()
47 {
48 return count;
49 } // end method getCount
50 } // end class Employee
DIANA HAIDAR 24
static class Members
static class variables and methods can be accessed even if no objects of the class have been instantiated.
Can be accessed by the class name and a dot (.) or an object's name and a dot (.).
Good programming practice: Invoke every static method by using the class name and a dot(.) to
emphasize that the method being called is a static method.
DIANA HAIDAR 25
static class Members
16 // show that count is 2 after creating two Employees
static method gc of class System 17 System.out.println( "\nEmployees after instantiation: " );
indicates that the garbage collector 18 System.out.printf( "via e1.getCount(): %d\n", e1.getCount() );
should make a best-effort attempt to 19 System.out.printf( "via e2.getCount(): %d\n", e2.getCount() );
reclaim objects eligible for garbage 20 System.out.printf( "via Employee.getCount(): %d\n",
collection, where it is possible that no 21 Employee.getCount() );
objects or only a subset of eligible objects 22
will be collected. 23 // get names of Employees
24 System.out.printf( "\nEmployee 1: %s %s\nEmployee 2: %s %s\n\n",
25 e1.getFirstName(), e1.getLastName(),
26 e2.getFirstName(), e2.getLastName() );
27
28 // in this example, there is only one reference to each Employee,
29 // so the following two statements cause the JVM to mark each
30 // Employee object for garbage collection
31 e1 = null;
32 e2 = null;
33
34 System.gc(); // ask for garbage collection to occur now
35
DIANA HAIDAR 26
static class Members
36 // show Employee count after calling garbage collector; count
37 // displayed may be 0, 1 or 2 based on whether garbage collector
38 // executes immediately and number of Employee objects collected
39 System.out.printf( "\nEmployees after System.gc(): %d\n",
40 Employee.getCount() );
41 } // end main
42 } // end class EmployeeTest
DIANA HAIDAR 27
final Instance Variables
The principle of least privilege states that code should be granted only the amount of privilege and access
that the code needs to accomplish its designated task.
Some instance variables need to be modifiable and some not.
The keyword final is used to specify that an instance variable is not modifiable (i.e. it is constant).
DIANA HAIDAR 28
final Instance Variables 1
2
// Fig. 8.15: Increment.java
// final instance variable in a class.
3
A final instance variable can be 4 public class Increment
initialized when declared, otherwise, 5 {
must be initialized by all the class's 6 private int total = 0; // total of all increments
constructors. 7 private final int INCREMENT; // constant variable (uninitialized)
8
Common programming error: 9 // constructor initializes final instance variable INCREMENT
10 public Increment( int incrementValue )
Attempting to modify a final instance 11 {
variable after it is initialized is a 12 INCREMENT = incrementValue; // initialize constant variable (once)
compilation error. 13 } // end Increment constructor
14
A final instance variable should also be 15 // add INCREMENT to total
declared static if it is initialized in its 16 public void addIncrementToTotal()
declaration, because accordingly its 17 {
value will never change. 18 total += INCREMENT;
19 } // end method addIncrementToTotal
20
21 // return String representation of an Increment object's data
22 public String toString()
23 {
24 return String.format( "total = %d", total );
25 } // end method toIncrementString
26 } // end class Increment
DIANA HAIDAR 29
final Instance Variables
1 // Fig. 8.16: IncrementTest.java
2 // final variable initialized with a constructor argument.
3
4 public class IncrementTest
5 {
6 public static void main( String args[] )
7 {
8 Increment value = new Increment( 5 );
9
10 System.out.printf( "Before incrementing: %s\n\n", value );
11
12 for ( int i = 1; i <= 3; i++ )
13 {
14 value.addIncrementToTotal();
15 System.out.printf( "After increment %d: %s\n", i, value );
16 } // end for
17 } // end main
18 } // end class IncrementTest
DIANA HAIDAR 30
Software Reusability
Software reusability (reusing existing classes) speeds the development of powerful, high-quality software.
Example: a programmer can concentrate on the Java graphic's capabilities rather than requiring the
knowledge of graphics on every computer platform.
Java is not just a programming language, however, Java API is a framework in which Java developers can
work to achieve true reusability and Rapid Application Development (RAD).
Documentation found at: java.sun.com/javase/6/docs/api/index.html
Good programming practice: Avoid reinventing the wheel. If Java API contains a class that meets your
program's requirements, reuse it.
DIANA HAIDAR 31
Data Abstraction and Encapsulation
An Abstract Data Type (ADT) actually captures two notions:
a data representation; and
the operations that can be performed on the data.
Example: The primitive type int is an abstract representation of an integer, where int is limited to a
particular range.
If an int falls outside this range, it produces an arithmetic overflow.
An int provides operations (e.g. addition, subtraction, etc.) that can be performed on the integer value
(data).
DIANA HAIDAR 32