Object
An object is an encapsulation of services (behavior) and attributes/data (state). Software objects are often used to model real-world objects you find in everyday life.
Two important characteristics of real-world objects: Have state, Have behavior
Software objects are modeled after real-world objects, so software objects have state and behavior. A software object maintains its state in variables and implements its behavior with methods
A class is a template or blueprint from which an object is actually made. This is similar to a C structure, but with functions. Unlike the classes we have written so far, a class for an object will contain variables for one object and methods that operate on those variables. An instance of a class is an object.
You may use a UML (Unified Modeling Language) class diagram to describe the class:
UML diagram for the Circle class:
Circle
-radius: double
-xCoord: double
-yCoord: double
+Circle( r:double, x:double, y:double) <<constructor>>
+circumference():double
+area():double
+getRadius():double
+getXCoord():double
+getYCoord():double
+setRadius(r: double)
+setXCoord(x: double)
+setYCoord(y: double)
+display()
Note: param-id : param-type may be a list
Optional before var-id or method-id: + (public), - (private), # (protected)
Optional access modifier (before class): public
Recall that public means class may be accessed from anywhere
There may be only one public class in a file
The name of the file must be the name of the public class (with the .java extension)
If NOT public (no access modifier), then the class and its members are accessible only by other classes within the same package (same directory) (more on packages later)
Class-scope Variables:
public variables may be accessed from any method that could access the class in which they are declared
private variables may be accessed only from methods inside its class (actual access may be limited)
static variables exist from when class is loaded to the end of the program and are called "class variables"
instance variables (any class-scope variable that's NOT static) exist when only when the class in which they are declared is instantiated until it's "garbage collected"
Note: Class-scope variables may be (public OR private OR none) AND (static OR not). No access specifier is package-scope
Method definitions:
Often include one or more constructor methods which are usually used to initialize the variables. A constructor is automatically called when a class is instantiated
Often include accessor methods which return the values of private variables, usually named getVarName
Sometimes include mutator/modifier methods which change the values of private variables, usually names setVarName
/*
Exercise 5.1: (.java document and the UML diagram) - Create a class Rectangle that has attributes (private instance variables) called length and width, each of which defaults to 1. Include either instance variables or methods for the area and perimeter.
- First write the UML diagram for the Rectangle class. Then write it in Java. If one or both of the parameters are <= 0, the constructor should leave or assign the default values, and the mutator should leave the length or width as it was before.
- Before you could test this, read page 5.7 first (not required to run this for the exercise).
*/
public class Exercise_5_1_Rectangle
{
private double d_length = 1;
private double d_width = 1;
public Exercise_5_1_Rectangle(double length, double width) // Constructor
{
// Only assign value if it is > 0 otherwise set value to 1
d_length = (length > 0) ? length : 1;
d_width = (width > 0) ? width : 1;
}
public double calculatePerimeter()
{
return 2 * (d_length + d_width);
}
public double calculateArea()
{
return d_length * d_width;
}
public double getLength()
{
return d_length;
}
public double getWidth()
{
return d_width;
}
public void setLength(double length)
{
d_length = length;
}
public void setWidth(double width)
{
d_width = width;
}
public static void main(String[] args)
{
// Exercise 5.2
}
}
/*
-- UML diagram
Exercise_5_1_Rectangle
-d_length: double
-d_width: double
+Exercise_5_1_Rectangle( length:double, width:double) <<constructor>>
+CalculatePerimeter():double
+CalculateArea():double
+getLength():double
+getWidth():double
+setLength(length: double)
+setWidth(width: double)
+display()
*/
In order to create a Java object (other than a String), you need to instantiate a class.
Syntax to instantiate a class: new ClassName( initial-values )
Note that the initial-values must match in number and type of at least one of the constructors for that class
Example: new Circle(1., 3., 5.);
Declaring Object Variables:
The syntax to declare an object variable is the same as declaring a variable of a primitive type, BUT the type is a class, and ...
an object variable will only refer to an object (after it is assigned), but is not the whole object (unlike C++)
you cannot copy whole objects by assigning an object variable to another object variable
/* Exercise 5.2: Write main (may be in the same or separate class from the Rectangle class) to test the Rectangle class (in Exercise 5.1).
Instantiate at least 2 Rectangle objects, assigning them to Rectangle variables in main.
Call several of the instance methods in the Rectangle class on those objects, displaying the results. */
public class Exercise_5_2_Rectangle
{
private double d_length = 1; // Remove initialization from here, not needed
private double d_width = 1;
public Exercise_5_2_Rectangle() // Default Constructor
{
d_length = 1;
d_width = 1;
}
public Exercise_5_2_Rectangle(double length, double width) // Constructor
{
// Only assign value if it is > 0 otherwise set value to 1
d_length = (length > 0) ? length : 1;
d_width = (width > 0) ? width : 1;
}
public double calculatePerimeter()
{
return 2 * (d_length + d_width);
}
public double calculateArea()
{
return d_length * d_width;
}
public double getLength()
{
return d_length;
}
public double getWidth()
{
return d_width;
}
public void setLength(double length)
{
// d_length = length; // -> NOT Correct in submitted homework 5.1
d_length = (length > 0) ? length : 1;
}
public void setWidth(double width)
{
//d_width = width; // -> NOT Correct in 5.1
d_width = (width > 0) ? width : 1;
}
public void display(){
System.out.println("Rectangle: length = "+ d_length + ", width = " + d_width +
", perimeter = "+ calculatePerimeter() + ", area = " + calculateArea()); // Only for test
}
public static void main(String[] args)
{
// Exercise 5.2
Exercise_5_2_Rectangle oRectangle1 = new Exercise_5_2_Rectangle(5,2);
Exercise_5_2_Rectangle oRectangle2 = new Exercise_5_2_Rectangle(0,-2);
Exercise_5_2_Rectangle oRectangle3 = new Exercise_5_2_Rectangle(); // Default constructor
// Test constructor
oRectangle1.display();
oRectangle2.display();
oRectangle3.display();
// test get set method
oRectangle3.setLength(10);
oRectangle3.setWidth(0);
System.out.println("Rectangle3: getLength() - " + oRectangle3.getLength() + ", getWidth() - " + oRectangle3.getWidth());
oRectangle3.display();
}
}
/* Output:
Rectangle: length = 5.0, width = 2.0, perimeter = 14.0, area = 10.0
Rectangle: length = 1.0, width = 1.0, perimeter = 4.0, area = 1.0
Rectangle: length = 1.0, width = 1.0, perimeter = 4.0, area = 1.0
Rectangle3: getLength() - 10.0, getWidth() - 1.0
Rectangle: length = 10.0, width = 1.0, perimeter = 22.0, area = 10.0
*/
this keyword refers to the object on which the method operates, for instance methods only (examples below)
A class may have more than one constructor or method with the same name, but eachmust be unique in its parameters (for example, differ in number of parameters and/or type of parameters). This is another example of method overloading.
Garbage Collection is the Java interpreter de-allocating memory for objects that have no references to them. This occurs sporadically, when "nothing else is going on" (e.g., waiting for input or events)
May call System.gc( ) to force garbage collection
/* Exercise 5.3: Write a class called Customer which has private instance variables for a name, account number and SavingsAccount. Include a constructor with a String, long, and double parameters which instantiates a SavingsAccount using the double parameter. Also include accessors (get) for each instance variable and a mutator(set) for the name only. You MUST also write the UML class diagram for this class.*/
public class Exercise_5_3_Customer
{
private String s_CustomerName;
private long l_CustomerAcctNum;
private Exercise_5_3_SavingsAccount oExercise_5_3_SavingsAccount;
public Exercise_5_3_Customer()
{
oExercise_5_3_SavingsAccount = new Exercise_5_3_SavingsAccount(); // in case, might prevent exception
}
public Exercise_5_3_Customer(String customerName, long customerAcctNum, double balance)
{
s_CustomerName = customerName;
l_CustomerAcctNum = customerAcctNum;
oExercise_5_3_SavingsAccount = new Exercise_5_3_SavingsAccount(balance);
}
public String getCustomerName()
{
return s_CustomerName;
}
public long getCustomerAcctNum()
{
return l_CustomerAcctNum;
}
public Exercise_5_3_SavingsAccount getSavingsAccount()
{
return oExercise_5_3_SavingsAccount;
}
public void setCustomerName(String CustomerName)
{
s_CustomerName = CustomerName; // is it require to check for empty string ??
}
public void display()
{
System.out.println("Customer Name: " + s_CustomerName);
System.out.println("Customer A/C no: " + l_CustomerAcctNum);
System.out.println("Customer Balance: " + oExercise_5_3_SavingsAccount.getBalance());
}
public static void main(String[] args)
{
// Test case
Exercise_5_3_Customer oExercise_5_3_Customer = new Exercise_5_3_Customer("ABC", 1234567890, 1000.00);
oExercise_5_3_Customer.display();
oExercise_5_3_Customer.oExercise_5_3_SavingsAccount.transaction(500);
oExercise_5_3_Customer.display();
}
}
/*
-- UML diagram
----------------------
Exercise_5_3_Customer
----------------------
-s_CustomerName: String
-l_CustomerAcctNum: long
-oExercise_5_3_SavingsAccount: Exercise_5_3_SavingsAccount
----------------------
+Exercise_5_3_Customer()
+Exercise_5_3_Customer(customerName: String, customerAcctNum: long, balance: double)
+getCustomerName(): String
+getCustomerAcctNum(): long
+getSavingsAccount(): Exercise_5_3_SavingsAccount
+setCustomerName(CustomerName:String)
+display()
----------------------
*/
/*
Output:
Customer Name: ABC
Customer A/C no: 1234567890
Customer Balance: 1000.0
Customer Name: ABC
Customer A/C no: 1234567890
Customer Balance: 1500.0
*/
public class Exercise_5_3_SavingsAccount
{
private static double annualIntRate; // default 0.
private double balance; // default 0.
public Exercise_5_3_SavingsAccount(double bal)
{
if( bal > 0 )
balance = bal;
// else leave as 0
} // end constructor
public Exercise_5_3_SavingsAccount(){ } //default const.
public double getBalance(){ return balance; }
public boolean transaction(double amount)
{
if( balance + amount >= 0 )
{
balance += amount;
return true;
}// end if
return false;
} // end transaction
public double addMonthlyInterest()
{
double interest;
interest = balance*annualIntRate/12.;
// should be rounded to nearest 100th
balance += interest;
return interest;
} // end addMonthlyInterest
public static boolean modifyIntRate(double newRate)
{
if( newRate >= 0 )
{
annualIntRate= newRate;
return true;
}// end if
return false;
} // end modifyIntRate
public static double getAnnualIntRate()
{
return annualIntRate;
} // end getAnnualIntRate
} // end SavingsAccount
Declaring arrays of objects is the same as declaring arrays of primitive types, except the type will be a class.
Assigning to each element of an array of objects, however, is very different. Each element must be assigned either null (default) or an object reference.
When allocating memory for an array using the new operator, each element will be initialized to null unless otherwise assigned.
/* Exercise 5.4: Declare an array of Customers in main. Write a static method (call from main) that returns an array of Customer objects. In this method, read how many Customers from the user (prompt first), then in a for loop, prompt and read a name, account number and savings balance, which will be passed to the Customer constructor when instantiating and assigning to an array element.*/
import java.util.Scanner;
public class Exercise_5_4_CustomerArray
{
static Scanner oScanner = new Scanner(System.in);
private String s_CustomerName;
private long l_CustomerAcctNum;
private Exercise_5_3_SavingsAccount oExercise_5_3_SavingsAccount;
public Exercise_5_4_CustomerArray()
{
oExercise_5_3_SavingsAccount = new Exercise_5_3_SavingsAccount(); // in case, might prevent exception
}
public Exercise_5_4_CustomerArray(String customerName, long customerAcctNum, double balance)
{
s_CustomerName = customerName;
l_CustomerAcctNum = customerAcctNum;
oExercise_5_3_SavingsAccount = new Exercise_5_3_SavingsAccount(balance);
}
public String getCustomerName()
{
return s_CustomerName;
}
public long getCustomerAcctNum()
{
return l_CustomerAcctNum;
}
public Exercise_5_3_SavingsAccount getSavingsAccount()
{
return oExercise_5_3_SavingsAccount;
}
public void setCustomerName(String CustomerName)
{
s_CustomerName = (CustomerName != null && CustomerName != "") ? CustomerName : s_CustomerName; // Check customer name is not null or empty string from a method or main function
}
public void display()
{
System.out.println("Customer Name: " + s_CustomerName);
System.out.println("Customer A/C no: " + l_CustomerAcctNum);
System.out.println("Customer Balance: " + oExercise_5_3_SavingsAccount.getBalance());
}
// Display customer array
public static void displayCustomerArray(Exercise_5_4_CustomerArray [] otempExercise_5_4_CustomerArray)
{
for(int i = 0; i < otempExercise_5_4_CustomerArray.length; i++)
{
System.out.println("Customer " + (i+1));
otempExercise_5_4_CustomerArray[i].display();
}
}
// Create array of Customers (Note: It is a static method3)
public static Exercise_5_4_CustomerArray [] CreateCustomerArray()
{
int i_numOfCustomer;
Exercise_5_4_CustomerArray [] otempExercise_5_4_CustomerArray;
System.out.println("Enter number of customers for whom you want to create bank accounts");
i_numOfCustomer = oScanner.nextInt();
if(i_numOfCustomer > 0)
{
// Only create memory location if user entered > 0
otempExercise_5_4_CustomerArray = new Exercise_5_4_CustomerArray[i_numOfCustomer];
//if(otempExercise_5_4_CustomerArray[0] == null) // it is null, memory is allocated when constructor is called later
// System.out.println("NULL Ha ha ha");
String customerName;
long accountNum;
double balance;
for(int i = 0; i < otempExercise_5_4_CustomerArray.length; i++)
{
// prompt and read a name, account number and savings balance
System.out.println("Enter information for Customer " + (i+1));
System.out.print("Name: ");
oScanner.nextLine(); // to flush new line before taking value from user
customerName = oScanner.nextLine();
System.out.print("Account #: ");
accountNum = oScanner.nextLong();
System.out.print("Bank Balance $: ");
balance = oScanner.nextDouble();
otempExercise_5_4_CustomerArray[i] = new Exercise_5_4_CustomerArray(customerName, accountNum, balance);
}
return otempExercise_5_4_CustomerArray;
}
else
{
return null; // Handle if required
}
}
public static void main(String[] args)
{
Exercise_5_4_CustomerArray [] oExercise_5_4_CustomerArray;
oExercise_5_4_CustomerArray = CreateCustomerArray();
if(oExercise_5_4_CustomerArray != null)
displayCustomerArray(oExercise_5_4_CustomerArray);
else
System.out.println("No customer has been created");
}
}
/* Output:
Enter number of customers for whom you want to create bank accounts
1
Enter information for Customer 1
Name: Firstname Lastname
Account #: 1212121
Bank Balance $: 1000
Customer 1
Customer Name: Firstname Lastname
Customer A/C no: 1212121
Customer Balance: 1000.0
*/
Static variables
May only be declared at class scope (not method scope)
Are allocated memory when the class in which it's declared is loaded
There is only one version of the static variable
May be accessed without instantiating its class
The order of initialization is declaration order
Static methods
May be called without instantiating its class
When called from another class, is called by giving: ClassName.methodName
May NOT access instance members (instance variables or methods) in its class
Static initialization block
Is a block of code preceded only by the keyword static
Is used to initialize static variables
A class may have more than one static initialization block
Get executed ONLY ONCE when the class is first loaded
Are executed in declaration order
In a static initialization block, any static variables or static methods referred to must be declared before the block
Is useful when the value of a static variable must be computed
Example of a static initialization block:
public class CreditAccount {
private static double intRate;
private static double difference = .05;
static { // assume Bank class has static var.
intRate = Bank.primeRate + difference;
// good to use if you want a loop to initialize!
}
// other parts of the CreditAccount class here
} // end class CreditAccount