Tuesday, January 25, 2011

Advance Object Oriented Programming.

In this example we will see Advance Object Oriented Programming.

We will use a simple banking example for this.

Steps:

  1. Create folder “src”. This will contain all java files.
  2. Then create AdvOOPTest1 to test the application.

The structure will be as follow

  • src/InsufficientFundsException.java
  • src/IllegalTransferException.java
  • src/Account.java
  • src/CustomerAccount.java
  • src/CurrentAccount.java
  • src/SavingsAccount.java
  • src/Banker.java
  • AdvOOPTest1.java

IllegalTransferException.java

package com.pravin.banking;

public class IllegalTransferException extends RuntimeException{}

Account.java

package com.pravin.banking;

/**
An abstract super-class for all account types in the bank.
@author Pravin
@see SavingsAccount
@see CurrentAccount
*/
public abstract class Account{
long id;

/**
Returns ID of this account.
*/
public long getId(){
return id;
}

/**
Returns the current-balance in this account.
*/
public abstract double getBalance();

/**
Credits the specified amount in this account.
*/
public abstract void deposit(double amount);

/**
Debits the specified amount from this account.
@throws InsufficientFundsException Specified amount cannot be withdrawn
*/
public abstract void withdraw(double amount) throws InsufficientFundsException;

/**
Transfer specified amount to another account.
@param amount Funds to transfer
@param other The target account
@throws InsufficientFundsException This account does not hold specified
amount
@throws IllegalTransferException Target account is identical to this
account
*/
public final void transfer(double amount, Account other)
throws InsufficientFundsException{
if(other == this)
throw new IllegalTransferException();
this.withdraw(amount);
other.deposit(amount);
}
}


CustomerAccount.java

package com.pravin.banking;

public abstract class CustomerAccount extends Account{
protected double balance;

public double getBalance(){
return balance;
}

public void deposit(double amount){
balance += amount;
}
}


CurrentAccount.java

package com.pravin.banking;

public final class CurrentAccount extends CustomerAccount{
public void withdraw(double amount){
balance -= amount;
}
}


SavingsAccount.java

package com.pravin.banking;

public final class SavingsAccount extends CustomerAccount
implements Profitable{
public static final double MIN_BALANCE = 500.0;

public SavingsAccount(){
balance = MIN_BALANCE;
}

public void withdraw(double amount) throws InsufficientFundsException{
if(balance - amount <>
throw new InsufficientFundsException();
balance -= amount;
}

public double addInterest(int period){
float rate = (balance <>
double interest = balance * rate * period / 100;
balance += interest;
return interest;
}
}


Banker.java

package com.pravin.banking;

public class Banker{
private static Banker singleton;

private long nextId;

private Banker(){
nextId = System.currentTimeMillis() % 1000000;
}

public static Banker getBanker(){
if(singleton == null)
singleton = new Banker();
return singleton;
}

public Account openAccount(double amount, boolean savings){
Account acc;
if(savings)
acc = new SavingsAccount();
else
acc = new CurrentAccount();
acc.id = nextId++;
acc.deposit(amount);
return acc;
}

public final Account openAccount(double amount){
return openAccount(amount, false);
}
}


AdvOOPTest1.java

import com.pravin.banking.*;

class AdvOOPTest1{
public static void main(String[] args){
Banker b = Banker.getBanker();
Account cust = b.openAccount(4500, true);
Account vend = b.openAccount(0);
try{
double amt = Double.parseDouble(args[0]);
cust.transfer(amt, vend);
}catch(InsufficientFundsException e){
System.out.println("ERROR: Transfer aborted due to lack of funds!");
}catch(Exception e){
System.out.printf("ERROR: %s%n", e);
}
System.out.printf("Customer Account ID is %d and Balance is %.2f%n", cust.getId(), cust.getBalance());
System.out.printf("Vendor Account ID is %d and Balance is %.2f%n", vend.getId(), vend.getBalance());
}
}

To compile:

javac -d . src/*.java

javac AdvOOPTest1.java

To run:

java AdvOOPTest1 2000

Object manipulation…

In this example we will see object manipulation i.e. for example Comparing two objects.

This example will demonstrate simple payroll system.

  1. Create folder with name “payroll”
  2. Create class “Employee” in payroll folder which will have logic to calculate salary for Employee.
  3. Now come out of the payroll folder. And create ObjMethTest class to test the code.

Employee.java

package payroll;

public class Employee{
private int id;
float rate;
protected int hours;
private static int count;

public Employee(int h, float r){
id = 101 + count++;
hours = h;
rate = r;
}

public Employee(){
this(0, 50);
}

public Employee(int i, int h, float r){
id = i;
hours = h;
rate = r;
}

public int getHours(){
return hours;
}

public void setHours(int value){
hours = value;
}

public float getRate(){
return rate;
}

public void setRate(float value){
rate = value;
}

public int getId(){
return id;
}

public double getNetIncome(){
double income = hours * rate;
int ot = hours - 180;
if(ot > 0)
income += 50 * ot;
return income;
}

public static int countEmployees(){
return count;
}

public int hashCode(){
return id;
}

public boolean equals(Object other){
if(other instanceof Employee){
Employee that = (Employee) other;
return (id == that.id) && (hours == that.hours) && (rate == that.rate);
}
return false;
}

public String toString(){
return id + " " + hours + " " + rate;
}

public void finalize(){
System.out.printf("Employee:%d finalized%n", id);
}
}

ObjMethTest.java

import payroll.Employee;

class ObjMethTest{
public static void main(String[] args){
Employee a = new Employee(175, 75);
Employee b = a;
Employee c = new Employee(101, 175, 75);
Employee d = new Employee();
System.out.printf("a is identical to b: %b%n", a == b);
System.out.printf("a is identical to c: %b%n", a == c);
System.out.printf("Hash-code of a: %d%n", a.hashCode());
System.out.printf("Hash-code of b: %d%n", b.hashCode());
System.out.printf("Hash-code of c: %d%n", c.hashCode());
System.out.printf("a is equal to b: %b%n", a.equals(b));
System.out.printf("a is equal to c: %b%n", a.equals(c));
System.out.printf("a: %s%n", a);
System.out.printf("b: %s%n", b);
System.out.printf("c: %s%n", c);
d = null;
System.gc();
}
}

To compile:

javac ObjMethTest.java

To run:

java ObjMethTest

OOP… Get to the actual work now. Part-II (Using import statement)

In this example we will use the import statement to access the classes declared inside the package. With this we can directly use the class name as its in the same directory (without pakage_name.class_name).


This example will demonstrate simple payroll system.

  1. Create folder with name “payroll”
  2. Create class “Employee” in payroll folder which will have logic to calculate salary for Employee.
  3. Create class “SalesPerson” in payroll folder which will have logic to calculate salary for Sales Person.
  4. Now come out of the payroll folder. And create BasicOOPTest2 class to test the code.

Employee.java

package payroll;


public class Employee{

private int id;

float rate;

protected int hours;

private static int count;


public Employee(int h, float r){

id = 101 + count++;

hours = h;

rate = r;

}


public Employee(){

this(0, 50);

}


public Employee(int i, int h, float r){

id = i;

hours = h;

rate = r;

}


public int getHours(){

return hours;

}


public void setHours(int value){

hours = value;

}


public float getRate(){

return rate;

}


public void setRate(float value){

rate = value;

}


public int getId(){

return id;

}


public double getNetIncome(){

double income = hours * rate;

int ot = hours - 180;

if(ot > 0)

income += 50 * ot;

return income;

}


public static int countEmployees(){

return count;

}


public int hashCode(){

return id;

}


public boolean equals(Object other){

if(other instanceof Employee){

Employee that = (Employee) other;

return (id == that.id) && (hours == that.hours) && (rate == that.rate);

}

return false;

}


public String toString(){

return id + " " + hours + " " + rate;

}


public void finalize(){

System.out.printf("Employee:%d finalized%n", id);

}

}


SalesPerson.java

package payroll;


public class SalesPerson extends Employee{

private double sales;


public SalesPerson(int h, float r, double s){

super(h, r);

sales = s;

}


public double getSales(){

return sales;

}


public void setSales(double value){

sales = value;

}


public double getNetIncome(){

double income = super.getNetIncome();

if(sales >= 25000)

income += 0.05 * sales;

return income;

}

}


BasicOOPTest2.java

import payroll.Employee;

import payroll.SalesPerson;


class BasicOOPTest2{

private static double averageIncome(Employee[] employees){

double total = 0;

for(Employee emp : employees){

total += emp.getNetIncome();

}

return total / employees.length;

}


private static double totalSales(Employee[] employees){

double total = 0;

for(Employee emp : employees){

if(emp instanceof SalesPerson){

SalesPerson sp = (SalesPerson) emp;

total += sp.getSales();

}

}

return total;

}


public static void main(String[] args){

Employee[] dept = {

new Employee(185, 52),

new Employee(205, 225),

new SalesPerson(180, 50, 60000),

new Employee(170, 95),

new SalesPerson(165, 45, 40000)

};

System.out.printf("Average Income: %.2f%n", averageIncome(dept));

System.out.printf("Total Sales: %.2f%n", totalSales(dept));

}

}

To compile:

javac BasicOOPTest2.java

To run:

java BasicOOPTest2

OOP… Get to the actual work now.

The main reason why the java is invented or I could say the soul of java. Its Object oriented nature. Let’s look now at Object Oriented Programming. Also now we will see how to create package in java.

This example will demonstrate simple payroll system.

  1. Create folder with name “payroll”
  2. Create class “Employee” in payroll folder which will have logic to calculate salary for Employee.
  3. Create class “SalesPerson” in payroll folder which will have logic to calculate salary for Sales Person.
  4. Now come out of the payroll folder. And create BasicOOPTest1 class to test the code.

Employee.java

package payroll;

public class Employee{
private int id;
float rate;
protected int hours;
private static int count;

public Employee(int h, float r){
id = 101 + count++;
hours = h;
rate = r;
}

public Employee(){
this(0, 50);
}

public Employee(int i, int h, float r){
id = i;
hours = h;
rate = r;
}

public int getHours(){
return hours;
}

public void setHours(int value){
hours = value;
}

public float getRate(){
return rate;
}

public void setRate(float value){
rate = value;
}

public int getId(){
return id;
}

public double getNetIncome(){
double income = hours * rate;
int ot = hours - 180;
if(ot > 0)
income += 50 * ot;
return income;
}

public static int countEmployees(){
return count;
}

public int hashCode(){
return id;
}

public boolean equals(Object other){
if(other instanceof Employee){
Employee that = (Employee) other;
return (id == that.id) && (hours == that.hours) && (rate == that.rate);
}
return false;
}

public String toString(){
return id + " " + hours + " " + rate;
}

public void finalize(){
System.out.printf("Employee:%d finalized%n", id);
}
}

SalesPerson.java

package payroll;

public class SalesPerson extends Employee{
private double sales;

public SalesPerson(int h, float r, double s){
super(h, r);
sales = s;
}

public double getSales(){
return sales;
}

public void setSales(double value){
sales = value;
}

public double getNetIncome(){
double income = super.getNetIncome();
if(sales >= 25000)
income += 0.05 * sales;
return income;
}
}

BasicOOPTest1.java

class BasicOOPTest1{
private static double incomeTax(payroll.Employee emp){
double i = emp.getNetIncome();
return (i <= 10000) ? 0 : 0.15 * (i - 10000);
}

public static void main(String[] args){
payroll.Employee jill = new payroll.Employee();
jill.setHours(185);
jill.setRate(52);
payroll.SalesPerson jack = new payroll.SalesPerson(185, 52, 80000);
System.out.printf("Jill's ID is %d, Income is %.2f and Tax is %.2f%n",
jill.getId(), jill.getNetIncome(), incomeTax(jill));
System.out.printf("Jack's ID is %d, Income is %.2f and Tax is %.2f%n",
jack.getId(), jack.getNetIncome(), incomeTax(jack));
System.out.printf("Number of Employees: %d%n",
payroll.Employee.countEmployees());
}
}

When we compile BasicOOPTest1.java the java compiler will automatically compiles Employee.java and SalesPerson.java files for you.

To compile:

javac BasicOOPTest1.java

To run:

java BasicOOPTest1

Send variable number of arguments to method. Another java 5 feature.

With variable argument feature we can send any number of arguments to same method. Useful when you are unsure that how many parameters will be passed to the method. One thing to keep in mind is that when we use this the variable or argument which represent varargs should be kept at last position of method, means it should be last argument to that method.

class VarArgTest{


private static double sum(double first, double second){

return first + second;

}


private static double sum(double first, double second, double third){

return first + second + third;

}


private static double sum(double first, double second, double... remaining){

double total = first + second;

for(double other : remaining)

total += other;

return total;

}

public static void main(String[] args){

System.out.printf("Sum of two: %f%n", sum(2.8, 3.7));

System.out.printf("Sum of three: %f%n", sum(2.8, 3.7, 4.4));

System.out.printf("Sum of five: %f%n", sum(2.8, 3.7, 4.4, 7.2, 9.1));

}

}


To compile:

javac VarArgTest.java

To run:

java VarArgTest

Finally execute the code… no matter what happens…

Here we use try finally to execute essential code, even if any severe error happens.

But when you try to kill the program the finally code will not be executed.


class TryFinallyTest{

public static void main(String[] args){

try{

double value = Double.parseDouble(args[0]);

double result = Math.sqrt(value);

System.out.printf("Square-root of %f is %f%n",

value, result);

}finally{

System.out.println("Goodbye!");

}

System.out.println("Done!");

}

}


To compile:

javac TryFinallyTest.java

To run:

java TryFinallyTest

Handling exceptions.

In java we use try catch to handle exception. In try we write the code which we think can/might cause the exception and in catch we write the solution to fix if the exception occurs.


class TryCatchTest{

public static void main(String[] args){

try{

double value = Double.parseDouble(args[0]);

double result = Math.sqrt(value);

System.out.printf("Square-root of %f is %f%n",

value, result);

}catch(ArrayIndexOutOfBoundsException e){

System.out.println("USAGE: java TryCatchTest number");

}catch(Exception e){

System.out.printf("ERROR: %s!%n", e);

}

System.out.println("Done!");

}

}

To compile:

javac TryCatchTest.java

To run:

java TryCatchTest