280 likes | 382 Views
ITI 1221. Introduction to Computing II Lab-6. Dewan Tanvir Ahmed University of Ottawa. Today’s Objective. Further understanding of linked structures Review of the concepts of interface and inheritance Questions and answers. LinkedPair. A class that represents a pair of Objects
E N D
ITI 1221. Introduction to Computing IILab-6 Dewan Tanvir Ahmed University of Ottawa
Today’s Objective • Further understanding of linked structures • Review of the concepts of interface and inheritance • Questions and answers
LinkedPair • A class that represents a pair of Objects • First element • Second element • For example: ( “computer”, “science” ) • “computer” is the first element • “science” is the second element • Either references might be null • ( null, “hello” ) • ( “hello”, null ) • ( null, null )
LinkedPair – Interface Pair • Write an interface, Pair, that can hold a pair of Objects. It includes • getFirst • It returns the first element in p • Example, p.getFirst() • getSecond • It returns the second element in p • Swap • It changes the order of the elements in p. • For example if p is the pair ( “computer”, “science” ), p.swap() would change p to be the pair ( “science”, “computer” ). • public interface Pair { • public abstract Object getFirst(); • public abstract Object getSecond(); • public abstract void swap(); • }
LinkedPair (cont..) • Create a class called LinkedPair which implements the interface Pair, and has the following: • A static nested class Elem private static class Elem { private Object value; private Elem next; private Elem( Object value, Elem next ) { this.value = value; this.next = next; } }
LinkedPair (cont..) • The instance variable first • points to the node containing the first element in the pair and • that node points to another node containing the second element in the pair. • A constructor with 2 parameters, both Objects, • which are used as the first and second elements in the new Pair instance. • public class LinkedPair implements Pair { private static class Elem { … } • private Elem first; • public LinkedPair( Object first, Object second ) { this.first = new Elem( first, new Elem( second, null ) ); } • public Object getFirst() { return first.value; }public Object getSecond() { return first.next.value; } • }
LinkedPair (cont..) • swap() method must work by changing the pointers that define the node order, it must not simply swap the values that are stored in the two nodes. public void swap() { Elem newFirst = first.next; newFirst.next = first; first.next = null; first = newFirst;} public String toString() { return "(" + first.value + "," + first.next.value + ")"; }
LinkedPair (cont..) • Add a method equals such that: • If p1 and p2 are two objects implementing Pair, • p1.equals( p2 ) • returns true if each element in p1 is equal to the corresponding element in p2, and • returns false otherwise. • This method must handle the case when p2 is null. • Question: what if p1 is null?
LinkedPair (cont..) public boolean equals( Object obj ) { if ( obj == null || ! ( obj instanceof Pair ) ) return false; Pair other = (Pair) obj; boolean firstEquals = false; if ( getFirst() == null && other.getFirst() == null ) { firstEquals = true; } else if ( getFirst() != null && getFirst().equals( other.getFirst() ) ) { firstEquals = true; }boolean secondEquals = false; if ( getSecond() == null && other.getSecond() == null ) { secondEquals = true; } else if ( getSecond() != null && getSecond().equals( other.getSecond() ) ) { secondEquals = true; } return firstEquals && secondEquals; }
LinkedPair (cont..) • Create a test class for your implementation, call it TestPair. • Play with this class class TestPair { public static void main( String[] args ) { Pair a = new LinkedPair( "computer", "science" ); System.out.println( a ); a.swap(); System.out.println( a ); Pair b = new LinkedPair( "computer", "science" ); if ( a.equals( b ) ) { System.out.println( "failed" ); } b.swap(); … }
LinkedPair (cont..) - Alternative • Create a new class Elem such that the class Elem is a top-level class (i.e. create a new file called Elem to implement the nodes of the linked structure). • Make the visibility of the class package and make its instance variable protected class Elem { protected Object value; protected Elem next; protected Elem( Object value, Elem next ) { this.value = value; this.next = next; } }
LinkedElems public class LinkedElems { private static class Elem { … } public static boolean equals( Elem p, Elem q ) { if ( p == null && q == null ) return true; Elem pp = p; Elem qq = q; boolean result = ( pp != null ) && ( qq != null ); while ( result && pp != null ) { if ( qq == null ) { result = false; // q is shorter than p } else if ( pp.value == null && qq.value != null ) { result = false; } else if ( pp.value != null && ( ! pp.value.equals( qq.value ) ) ) { result = false; } else { pp = pp.next; qq = qq.next; } } if ( pp == null && qq != null ) { result = false; // p is shorter than q } return result; }
LinkedElems (cont..) public static void main( String[] args ) { Elem p; p = new Elem( "A", null ); p.next = new Elem( new Integer( 3 ), null ); p.next.next = new Elem( new Boolean( true ), null ); Elem q; q = new Elem( "A", new Elem( new Integer( 3 ), null ) ); if ( equals( p, q ) ) { System.out.println( "[1] failed" ); } q.next.next = new Elem( new Boolean( true ), null ); if ( ! equals( p, q ) ) { System.out.println( "[2] failed" ); }
LinkedPair (cont..) - Alternative • Modify the class Elem so that the instance variables are private. You will be forced to create access methods, getters and setters. public class Elem { private Object value; private Elem next; public Elem( Object value, Elem next ) { this.value = value; this.next = next; } public Object getValue() { return value; } public void setValue( Object value ) { this.value = value; } public Elem getNext() { return next; } public void setNext( Elem next ) { this.next = next; } }
Inheritance – Once again • The company Java Financial Solutions is developing a new software system for tracking professional expenses. • You are part of the software development team responsible for the hierarchy of classes to represent expenses.
Inheritance – Once again • All expenses have a description (a character string) • All the transportation expenses have a destination (a character string) • A transportation expense using a private car has a distance (of type int) • A transportation expense by air has a fixed amount (of type double) specified when a new transportation expense is created • All the meal expenses have an attribute which represents the number of meals • All the expenses have a method to calculate the amount represented by this expense: • The amount for a transportation expense using a private car is a fixed rate times the distance traveled • The amount for a transportation expense by air is a fixed amount (specified when a new transportation expense is created) • The amount for a meal expense is the number of meals times a fixed rate. The rate depends on the kind of meal: Breakfast, Lunch or Dinner
Inheritance – Once again • Class Expense (abstract class): • An instance variable for description • Constructor with one parameter for description initial value • Access method for description • An abstract method to get the amount of the expense public abstract class Expense { private String description; public Expense( String description ) { this.description = description; } public String getDescription() { return description; } public abstract double getAmount(); }
Inheritance – Once again • Class Transportation (an abstract extension of the class Expense): • An instance variable for destination • Constructor with one extra parameter for destination initial value public abstract class Transportation extends Expense { private String destination; public Transportation( String description, String destination ) { super( description ); this.destination = destination; } }
Inheritance – Once again • Class Meal (an abstract extension of the class Expense): • An instance variable for the number of meals • Constructor with one extra parameter for number of meals initial value • Access method for the number of meals • Implementation of getAmount() method. The amount for a meal expense is the number of meals times a fixed rate • An abstract method for getting the rate. The rate depends on the kind of meal: Breakfast, Lunch or Dinner public abstract class Meal extends Expense { private int numberOfMeals; public Meal( String description, int numberOfMeals ) { super( description ); this.numberOfMeals = numberOfMeals; } public int getNumberOfMeals() { return numberOfMeals; } public double getAmount() { return getNumberOfMeals() * getRate(); } public abstract double getRate(); }
Inheritance – Once again • Class PrivateCar (an extension of the class Transportation): • A static variable for the rate (0.427) • An instance variable for the distance • Constructor with one extra parameter for distance initial value • Access method for distance • Implementation of getAmount() method. The amount for a private car expense is the distance times the rate public class PrivateCar extends Transportation { public static double RATE = 0.427; private int distance; public PrivateCar( String description, String destination, int distance ) { super( description, destination ); this.distance = distance; } public int getDistance() { return distance; } public double getAmount() { return distance * RATE; } }
Inheritance – Once again • Class Airfare (an extension of the class Transportation): • An instance variable for the amount • Constructor with one extra parameter for amount initial value • Access method for the amount public class Airfare extends Transportation { public double amount; public Airfare( String description, String destination, double amount ) { super( description, destination ); this.amount = amount; } public double getAmount() { return amount; } }
Inheritance – Once again • Class Breakfast (an extension of the class Meal): • A static variable for the rate (11.55) • Constructor with no extra parameter • Access method for the rate public class Breakfast extends Meal { public static double RATE = 11.55; public Breakfast( String description, int numberOfMeals ) { super( description, numberOfMeals ); } public double getRate() { return RATE; } }
Inheritance – Once again • Class Lunch (an extension of the class Meal): • A static variable for the rate (11.30) • Constructor with no extra parameter • Access method for the rate public class Lunch extends Meal { public static double RATE = 11.30; public Breakfast( String description, int numberOfMeals ) { super( description, numberOfMeals ); } public double getRate() { return RATE; } }
Inheritance – Once again • Class Dinner (an extension of the class Meal): • A static variable for the rate (31.80) • Constructor with no extra parameter • Access method for the rate public class Dinner extends Meal { public static double RATE = 31.80; public Breakfast( String description, int numberOfMeals ) { super( description, numberOfMeals ); } public double getRate() { return RATE; } }
Inheritance – Once again • Class ExpenseTracker • Complete the partial implementation of the class ExpenseTracker • An ExpenseTracker is used to store Expenses: • Add the type of the elements of the array expenses • Complete the constructor • Complete the implementation of the method double getTotal(). • The method double getTotal() returns the total amount for all the expenses that are currently stored in the ExpenseTracker
Inheritance – Once again • public class ExpenseTracker { • private Expense[] expenses; • private int size; • public ExpenseTracker( int capacity ) { • expenses = new Expense[ capacity ]; • size = 0; • } • public boolean add( Expense e ) { • expenses[ size++ ] = e; • return true; • } • public double getTotal() { • double total = 0.0; • for ( int i=0; i<size; i++ ) { • total = total + expenses[ i ].getAmount(); • } • return total; • } • } • }
Inheritance – Once again public class Run { public static void main( String[] args ) { ExpenseTracker epro = new ExpenseTracker( 10 ); epro.add( new PrivateCar( "ACFAS 2004", "Montreal (QC)", 430 ) ); epro.add( new Airfare( "IWBRA 2005", "Atlanta (GA)", 204.0 ) ); epro.add( new Breakfast( "IWBRA 2005", 2 ) ); epro.add( new Lunch( "IWBRA 2005", 3 ) ); epro.add( new Dinner( "IWBRA 2005", 2 ) ); System.out.println( "total = " + epro.getTotal() ); } } Its output is as follows: total = 508.21000000000004