Category Archives: Homework

Chapter 7: Polymorphism in Inheritance and Interfaces: BankAccount


Polymorphism and Inheritance

In Java, the type of a variable does not completely determine the type of the object to which it refers. For example, a variable of type BankAccount can hold a reference to an actual BankAccount object or a subclass object such as SavingsAccount. You already encountered this phenomenon with variables whose type was an interface. A variable whose type is Measurable holds a reference to an object of a class that implements the Measurable interface, perhaps a Coin object or an object of an entirely different class.

What happens when you invoke a method? For example,

BankAccount anAccount = new CheckingAccount();
anAccount.deposit(1000);

Which deposit method is called? The anAccount parameter has type BankAccount, so it would appear as if BankAccount.deposit is called. On the other hand, the CheckingAccount class provides its own deposit method that updates the transaction count. The anAccount field actually refers to an object of the subclass CheckingAccount, so it would be appropriate if the CheckingAccount.deposit method were called instead.

In Java, method calls are always determined by the type of the actual object, not the type of the object reference. That is, if the actual object has the type CheckingAccount, then the CheckingAccount.deposit method is called. It does not matter that the object reference is stored in a field of type BankAccount. The ability to refer to objects of multiple types with varying behavior is called polymorphism .

If polymorphism is so powerful, why not store all account references in variables of type Object? This does not work because the compiler needs to check that only legal methods are invoked. The Object type does not define a deposit method—the BankAccount type (at least) is required to make a call to the deposit method.

Have another look at the transfer method to see polymorphism at work. Here is the implementation of the method:


public void transfer(double amount, BankAccount other)
{
   withdraw(amount);
   other.deposit(amount);
}


Suppose you call

anAccount.transfer(1000, anotherAccount);

Two method calls are the result:

anAccount.withdraw(1000);
anotherAccount.deposit(1000);

Depending on the actual types of anAccount and anotherAccount, different versions of the withdraw and deposit methods are called.

If you look into the implementation of the transfer method, it may not be immediately obvious that the first method call

withdraw(amount);

depends on the type of an object. However, that call is a shortcut for

this.withdraw(amount);

The this parameter holds a reference to the implicit parameter, which can refer to a BankAccount or a subclass object.

The following program calls the polymorphic withdraw and deposit methods.
Manually calculate what the program should print on edmodo.com for each account balance, and confirm that the correct methods have in fact been called.

AccountTester is the driver class:

  /**
     This program tests the BankAccount class and
     its subclasses.
  */
  public class AccountTester
  {
     public static void main(String[] args)
     {
        SavingsAccount momsSavings
             = new SavingsAccount(0.5);

       CheckingAccount harrysChecking
             = new CheckingAccount(100);

       momsSavings.deposit(10000);

       momsSavings.transfer(2000, harrysChecking);
       harrysChecking.withdraw(1500);
       harrysChecking.withdraw(80);

       momsSavings.transfer(1000, harrysChecking);
       harrysChecking.withdraw(400);

       // Simulate end of month
       momsSavings.addInterest();
       harrysChecking.deductFees();

       System.out.println("Mom\'s savings balance: "
             + momsSavings.getBalance());
       System.out.println("Expected: ????");

       System.out.println("Harry\'s checking balance: "
             + harrysChecking.getBalance());
       System.out.println("Expected: ????");
    }
 }

BankAccount Class:

  /**
     A bank account has a balance that can be changed by
     deposits and withdrawals.
  */
  public class BankAccount
  {
     /**
        Constructs a bank account with a zero balance.
     */
    public BankAccount()
    {
       balance = 0;
    }

    /**
       Constructs a bank account with a given balance.
       @param initialBalance the initial balance
    */
    public BankAccount(double initialBalance)
    {
       balance = initialBalance;
    }

    /**
       Deposits money into the bank account.
       @param amount the amount to deposit
    */
    public void deposit(double amount)
    {
       balance = balance + amount;
    }

    /**
       Withdraws money from the bank account.
       @param amount the amount to withdraw
    */
    public void withdraw(double amount)
    {
       balance = balance - amount;
    }

    /**
       Gets the current balance of the bank account.
       @return the current balance
    */
    public double getBalance()
    {
       return balance;
    }

    /**
       Transfers money from the bank account to another account.
       @param amount the amount to transfer
       @param other the other account
    */
    public void transfer(double amount, BankAccount other)
    {
       withdraw(amount);
       other.deposit(amount);
    }

    private double balance;
 }

CheckingAccount Class derived from BankAccount:

  /**
     A checking account that charges transaction fees.
  */
  public class CheckingAccount extends BankAccount
  {
     /**
        Constructs a checking account with a given balance.
        @param initialBalance the initial balance
     */
    public CheckingAccount(double initialBalance)
    {
       // Construct superclass
       super(initialBalance);

       // Initialize transaction count
       transactionCount = 0;
    }

    public void deposit(double amount)
    {
       transactionCount++;
       // Now add amount to balance
       super.deposit(amount);
    }

    public void withdraw(double amount)
    {
       transactionCount++;
       // Now subtract amount from balance
       super.withdraw(amount);
    }

    /**
       Deducts the accumulated fees and resets the
       transaction count.
    */
    public void deductFees()
    {
       if (transactionCount > FREE_TRANSACTIONS)
       {
          double fees = TRANSACTION_FEE *
                (transactionCount - FREE_TRANSACTIONS);
          super.withdraw(fees);
       }
       transactionCount = 0;
    }

    private int transactionCount;

    private static final int FREE_TRANSACTIONS = 3;
    private static final double TRANSACTION_FEE = 2.0;
 }



SavingsAccount derived from BankAccount:

 /**
   An account that earns interest at a fixed rate.
 */
 public class SavingsAccount extends BankAccount
 {
   /**
      Constructs a bank account with a given interest rate.
      @param rate the interest rate
   */
   public SavingsAccount(double rate)
   {
      interestRate = rate;
   }

   /**
      Adds the earned interest to the account balance.
   */
   public void addInterest()
   {
      double interest = getBalance() * interestRate / 100;
      deposit(interest);
   }

   private double interestRate;
}


Look up the definition of the standard Comparable interface in the API documentation. Modify the DataSet class to accept Comparable objects. With this interface, it is no longer meaningful to compute the average. The DataSet class should record the minimum and maximum data values. Test your modified DataSet class by adding a number of String objects. (The String class implements the Comparable interface.)

Complete the following class in your solution:

DataSet Class takes objects of classes that implement the Comparable interface:

/**
   Computes the minimum and maximum of a set of Comparable values.
*/
public class DataSet
{
   /**
      Constructs an empty data set.
   */
   public DataSet()
   {
      . . .
   }

   /**
      Adds a data value to the data set.
      @param x a data value
   */
   public void add(Comparable x)
   {
      . . .
   }

   /**
      Gets the largest of the added data.
      @return the maximum or null if no data has been added
   */
   public Comparable getMaximum()
   {
      . . .
   }

   /**
      Gets the largest of the added data.
      @return the maximum or null if no data has been added
   */
   public Comparable getMinimum()
   {
      . . .
   }

   . . .
}


Use the following class as your tester class:

/**
   This program demonstrates the use of the DataSet that accepts
   instances of the Comparable interface.
*/
public class DataSetTester
{
   public static void main(String[] args)
   {
      DataSet data = new DataSet();
   
      data.add("Helen");
      data.add("Andy");
      data.add("Robert");
      data.add("Vicky");

      Comparable max = data.getMaximum();
      Comparable min = data.getMinimum();
      System.out.println("Maximum: " + max);
      System.out.println("Expected: Vicky");
      System.out.println("Minimum: " + min);
      System.out.println("Expected: Andy");
   }
}

Assignments:
1. From the classes discussed above, draw the UML class diagram and show/demonstrate late binding in inheritance for the BankAccount classes.

  1. Show/demonstrate late binding in inheritance for the StaffCrew classes.
    abstract public class StaffCrew
    Volunteer extends StaffCrew
    FullTimeStaff extends StaffCrew
    Supervisor extends FullTimeStaff
    PartTime extends FullTimeStaff

Chapter 7: Polymorphism and Interfaces Concepts

Classwork: Constructors and Methods behavior diagrams.

Polymorphism and Interfaces:

In Java, all instance methods are polymorphic. The same computation works for objects of many shapes, and adapts itself to the nature of the objects.

Polymorphism denotes the principle that behavior can vary depending on the actual type of an object.

When the virtual machine calls an instance method, it locates the method of the implicit parameter’s class. This is called dynamic method lookup.

Dynamic method lookup enables a programming technique called polymorphism.

There is an important difference between polymorphism and overloading. The compiler picks an overloaded method when translating the program, before the program ever runs. This method selection is called early binding.

Interfaces: when selecting the appropriate getMeasure method in a call x.getMeasure(), the compiler does not make any decision when translating the method as mentioned above. The program has to run before anyone can know what is stored in x. Therefore, the virtual machine, and not the compiler, selects the appropriate method. This method selection is called late binding.

Using a polymorphic reference as the formal parameter to a method is a powerful technique. It allows the method to control the types of parameters passed into it, yet gives it the flexibility to accept arguments of various types.

Looking again at the driver for the DataSet of Measurable objects, we have seen this code:

public static void main(String[] args)
   {
      DataSet bankData = new DataSet();
      
      bankData.add(new BankAccount(3000));
      bankData.add(new BankAccount(10000));
      bankData.add(new BankAccount(2000));

      System.out.println("Average balance = " + bankData.getAverage());
      
      Measurable max = bankData.getMaximum();
      System.out.println("Highest balance = " + max.getMeasure());
      //System.out.println("Get bank balance = " + max.getBalance()); 
      // ERROR since "max" is not an object of BankAccount
      BankAccount maxAccount = (BankAccount) max; 
      // casting from interfaces to classes
      // max ---> maxAccount ( object of BankAccount )
      System.out.println("Get bank balance = " + maxAccount.getBalance());
      // NO ERROR
      ....
}

To protect against bad casts, you can use the instanceof operator.

Here is a good example:

if ( max instaceof BankAccount )
   {
      BankAccount maxAccount = (BankAccount) max; 
      System.out.println("Get bank balance = " + maxAccount.getBalance());
    }

Homework:
Check edmodo.com

Chapter 7: Polymorphism and Inheritance: Pizza, Staff and Hospital

Polymorphism and Inheritance

Indirect use of class members
There is a subtle feature of inheritance that is worth noting at this point. The visibility modifiers determine whether a variable or method is inherited into a subclass. If a variable or method is inherited, it can be referenced directly in the subclass by name, as if it were declared locally in the subclass. However, all variables and methods that are defined in a parent class exist for an object of a derived class, even though they can’t be referenced directly. They can, however, be referenced indirectly.
Let’s look at an example that demonstrates this situation. The program shown in Listing 7.17 contains a main method that instantiates a Pizza object and invokes a method to determine how many calories the pizza has per serving due to its fat content.

//********************************************************************
   //  FoodAnalysis.java       Author: Lewis/Loftus
   //
   //  Demonstrates indirect referencing through inheritance.
   //********************************************************************
   public class FoodAnalysis

The FoodItem class shown in Listing 7.18 represents a generic type of food. The constructor of FoodItem accepts the number of grams of fat and the number of servings of that food. The calories method returns the number of calories due to fat, which the caloriesPerServing method invokes to help compute the number of fat calories per serving.

//********************************************************************
//  FoodItem.java       Author: Lewis/Loftus
//
//  Represents an item of food. Used as the parent of a derived class
//  to demonstrate indirect referencing through inheritance.
//********************************************************************
public class FoodItem

The Pizza class, shown in Listing 7.19, is derived from FoodItem class, but it adds no special functionality or data. Its constructor calls the constructor of FoodItem, using the super reference assuming that there are eight servings per pizza.
Note that the Pizza object called special in the main method is used to invoke the method caloriesPerServing, which is defined as a public method of FoodItem and is therefore inherited by Pizza. However, caloriesPerServing calls calories, which is declared private, and is therefore not inherited by Pizza. Furthermore, calories references the variable fatGrams and the constant CALORIES_PER_GRAM, which are also declared with private visibility.
Even though Pizza did not inherit calories, fatGrams, or CALORIES_PER_GRAM, they are available for use indirectly when the Pizza object needs them. The Pizza class cannot refer to them directly by name because they are not inherited, but they do exist. Note that a FoodItem object was never created or needed.

//********************************************************************
  //  Pizza.java       Author: Lewis/Loftus
  //
  //  Represents a pizza, which is a food item. Used to demonstrate
  //  indirect referencing through inheritance.
  //********************************************************************
  public class Pizza extends FoodItem
  {
     //-----------------------------------------------------------------
     //  Sets up a pizza with the specified amount of fat (assumes
     //  eight servings).
     //-----------------------------------------------------------------
     public Pizza (int fatGrams)
     {
        super (fatGrams, 8);
}
}

*** Answer questions about each variable and method declared in the FoodItem class. Indicate whether it exists in or is inherited by the Pizza class. Note that every FoodItem member exists in the Pizza class, no matter how it is declared. The items that are not inherited can be referenced only indirectly.

polymorphism

Usually, the type of a reference variable matches exactly the class of the object to which it refers. That is, if we declare a reference as follows, the bishop reference is used to refer to an object created by instantiating the ChessPiece class.

ChessPiece bishop;

However, the relationship between a reference variable and the object it refers to is more flexible than that.
The term polymorphism can be defined as “having many forms.” A polymorphic reference is a reference variable that can refer to different types of objects at different points in time. The specific method invoked through a polymorphic reference can change from one invocation to the next.
Consider the following line of code:

obj.doIt();

If the reference obj is polymorphic, it can refer to different types of objects at different times. If that line of code is in a loop or in a method that is called more than once, that line of code might call a different version of the doIt method each time it is invoked.
At some point, the commitment is made to execute certain code to carry out a method invocation. This commitment is referred to as binding a method invocation to a method definition. In most situations, the binding of a method invocation to a method definition can occur at compile time. For polymorphic references, however, the decision cannot be made until run time. The method definition that is used is based on the object that is being referred to by the reference variable at that moment. This deferred commitment is called late binding or dynamic bind- ing. It is less efficient than binding at compile time because the decision must be made during the execution of the program. This overhead is generally acceptable in light of the flexibility that a polymorphic reference provides.
We can create a polymorphic reference in Java in two ways: using inheritance and using interfaces. This section describes how we can accomplish polymorphism using inheritance. Later in the chapter we revisit the issue of interfaces and describe how polymorphism can be accomplished using interfaces as well.

In Java, a reference that is declared to refer to an object of a particular class can also be used to refer to an object of any class related to it by inheritance. For example, if the class Mammal is used to derive the class Horse, then a Mammal reference can be used to refer to an object of class Horse. This ability is
shown in the following code segment:
Mammal pet;
Horse secretariat = new Horse();
pet = secretariat; // a valid assignment

The reverse operation, assigning the Mammal object to a Horse reference, is also valid but requires an explicit cast. Assigning a reference in this direction is generally less useful and more likely to cause problems because although a horse has all the functionality of a mammal (because a horse “is-a” mammal), the reverse is not necessarily true.
This relationship works throughout a class hierarchy. If the Mammal class were derived from a class called Animal, the following assignment would also be valid:

Animal creature = new Horse();

Carrying this to the limit, an Object reference can be used to refer to any object because ultimately all classes are descendants of the Object class. An ArrayList, for example, uses polymorphism in that it is designed to hold Object references. That’s why an ArrayList can be used to store any kind of object. In fact, a particular ArrayList can be used to hold several different types of objects at one time because, in essence, they are all Object objects.

The reference variable creature, as defined in the previous section, can be polymorphic because at any point in time it can refer to an Animal object, a Mammal object, or a Horse object. Suppose that all three of these classes have a method called move that is implemented in different ways (because the child class overrode the definition it inherited). The following invocation calls the move method, but the particular version of the method it calls is determined at runtime:
creature.move();
At the point when this line is executed, if creature currently refers to an Animal object, the move method of the Animal class is invoked. Likewise, if creature currently refers to a Mammal or Horse object, the Mammal or Horse version of move is invoked, respectively.
Of course, since Animal and Mammal represent general concepts, they may be defined as abstract classes. This situation does not eliminate the ability to have polymorphic references. Suppose the move method in the Mammal class is abstract, and is given unique definitions in the Horse, Dog, and Whale classes (all derived from Mammal). A Mammal reference variable can be used to refer to any objects created from any of the Horse, Dog, and Whale classes, and
can be used to execute the move method on any of them.
Let’s look at another situation. Consider the class hierarchy shown below. The classes in it represent various types of employees that might be employed at a particular company. Let’s explore an example that uses this hierarchy to demonstrate several inheritance issues, including polymorphism.
The Firm class shown in Listing 7.16 contains a main driver that creates a Staff of employees and invokes the payday method to pay them all. The program output includes information about each employee and how much each is paid (if anything).

PolymorphismInheritance

ClassesDependencies

The classes in this UML represent various types of staff members in a company.

The Hospital class is a main driver that creates a Staff of employees and invokes the payday method to pay them all.

The program outputs information about the staff and how much each is paid.

The Staff class maintains an array of objects that represents the staff in a hospital.

The array is declared to hold StaffCrew references, but it is actually filled with objects created from several other classes, such as Supervisor and FullTimeStaff.

These classes are all descendants of the StaffMember class, so the assignments are valid. The staffList array is filled with polymorphic references.

The payday method of the Staff class traverses the list of employees, printing their information and calling their pay methods to determine how much each employee should be paid.

The invocation of the pay method is polymorphic, because each class has its own version of the pay method.

The StaffCrew class is abstract. It is not designed to be instantiated or to be any of the members of the staff. It is designed to be a parent of all staff member classes. Each staff has a name, address, and phone number, so variables to store these values are declared in the StaffCrew class and are inherited by all descendants.

The StaffCrew class contains a toString method to return the information managed by the StaffCrew class. It also contains an abstract method called basicPay, which takes no parameters and returns a value of type double. It would not make sense to define this method in this class since it is different for every staff member.

The children classes provide the definition for basicPay so they are dynamically selected at run time. This is called polymorphism. It lets us treat similar objects in consistent but unique ways.

//********************************************************************
//  Demonstrates polymorphism and inheritance.
//********************************************************************

public class Hospital
{
   //-----------------------------------------------------------------
   //  Creates a staff for a hospital and pays them.
   //-----------------------------------------------------------------
   public static void main (String[] args)
   {
      Staff personnel = new Staff();

      personnel.payday();
   }
}

//********************************************************************
//  Represents the personnel staff of a particular hospital.
//********************************************************************

public class Staff
{
   private StaffCrew[] staffList;

   //-----------------------------------------------------------------
   //  Constructor: Sets up the list of staff members.
   //-----------------------------------------------------------------
   public Staff ()
   {
      staffList = new StaffCrew[6];

      staffList[0] = new Supervisor ("Mary", "111 ABC Rd",
         "555-4444", "123456789", 2000.00);

      staffList[1] = new FullTimeStaff ("John", "222 DEF Rd",
         "555-5555", "234567891", 1000.00);
      staffList[2] = new FullTimeStaff ("Alice", "333 GHI Rd",
         "555-3333", "345678912", 1100.00);

      staffList[3] = new PartTime ("Bob", "444 JKL Rd",
         "555-2222", "456789123", 12.00);

      staffList[4] = new Volunteer ("Tom", "555 MNO Rd",
         "555-1111");
      staffList[5] = new Volunteer ("Jill", "666 PQR Rd",
         "555-7282");

      ((Supervisor)staffList[0]).grantBonus (300.00);

      ((PartTime)staffList[3]).addHours (25);
   }

   //-----------------------------------------------------------------
   //  Pays all staff members.
   //-----------------------------------------------------------------
   public void payday ()
   {
      double amount;

      for (int count=0; count < staffList.length; count++)
      {
         System.out.println (staffList[count]);

         amount = staffList[count].basicPay();  // polymorphic

         if (amount == 0.0)
            System.out.println ("Thanks!");
         else
            System.out.println ("Paid: " + amount);

         System.out.println ("-----------------------------------");
      }
   }
}

//********************************************************************
//  Represents any crew member.
//********************************************************************

abstract public class StaffCrew
{
   protected String name;
   protected String address;
   protected String phone;

   //-----------------------------------------------------------------
   //  Constructor: Sets up this staff crew using the specified
   //  information.
   //-----------------------------------------------------------------
   public StaffCrew (String eName, String eAddress, String ePhone)
   {
      name = eName;
      address = eAddress;
      phone = ePhone;
   }

   //-----------------------------------------------------------------
   //  Returns a string including the basic full time staff information.
   //-----------------------------------------------------------------
   public String toString()
   {
      String result = "Name: " + name + "\n";

      result += "Address: " + address + "\n";
      result += "Phone: " + phone;

      return result;
   }

   //-----------------------------------------------------------------
   //  Derived classes must define the pay method for each type of
   //  full time staff.
   //-----------------------------------------------------------------
   public abstract double basicPay();
}

//********************************************************************
//  Represents a staff member that works as a volunteer.
//********************************************************************

public class Volunteer extends StaffCrew
{
   //-----------------------------------------------------------------
   //  Constructor: Sets up this volunteer using the specified
   //  information.
   //-----------------------------------------------------------------
   public Volunteer (String eName, String eAddress, String ePhone)
   {
      super (eName, eAddress, ePhone);
   }

   //-----------------------------------------------------------------
   //  Returns a zero pay value for this volunteer.
   //-----------------------------------------------------------------
   public double basicPay()
   {
      return 0.0;
   }
}

//********************************************************************
//  Represents a general paid full time staff.
//********************************************************************

public class FullTimeStaff extends StaffCrew
{
   protected String IDNumber;
   protected double payRate;
   
   //-----------------------------------------------------------------
   //  Constructor: Sets up this full time staff with the specified
   //  information.
   //-----------------------------------------------------------------
   public FullTimeStaff (String eName, String eAddress, String ePhone,
                    String eIDNumber, double rate)
   {
      super (eName, eAddress, ePhone);

      IDNumber = anIDNumber;
      payRate = rate;
   }

   //-----------------------------------------------------------------
   //  Returns information about a full-time staff as a string.
   //-----------------------------------------------------------------
   public String toString()
   {
      String result = super.toString();

      result += "\nID Number: " + IDNumber;

      return result;
   }

   //-----------------------------------------------------------------
   //  Returns the pay rate for this full-time staff.
   //-----------------------------------------------------------------
   public double basicPay()
   {
      return payRate;
   }
}

//********************************************************************
//  Represents an Supervisor staff member, who can earn a bonus.
//********************************************************************

public class Supervisor extends FullTimeStaff
{
   private double bonus;

   //-----------------------------------------------------------------
   //  Constructor: Sets up this supervisor with the specified
   //  information.
   //-----------------------------------------------------------------
   public Supervisor (String eName, String eAddress, String ePhone,
                     String eIDNumber, double rate)
   {
      super (eName, eAddress, ePhone, eIDNumber, rate);

      bonus = 0;  // bonus has yet to be awarded
   }

   //-----------------------------------------------------------------
   //  Grants the specified bonus to this supervisor.
   //-----------------------------------------------------------------
   public void grantBonus (double execBonus)
   {
      bonus = execBonus;
   }

   //-----------------------------------------------------------------
   //  Computes and returns the pay for a supervisor, which is the
   //  regular full-time staff payment plus a one-time bonus.
   //-----------------------------------------------------------------
   public double basicPay()
   {
      double payment = super.basicPay() + bonus;

      bonus = 0;

      return payment;
   }
}

//********************************************************************
//  Represents a full time staff that gets paid by the hour.
//********************************************************************

public class PartTime extends FullTimeStaff
{
   private int hoursWorked;

   //-----------------------------------------------------------------
   //  Constructor: Sets up this part time staff using the specified
   //  information.
   //-----------------------------------------------------------------
   public PartTime (String eName, String eAddress, String ePhone,
                  String eIDNumber, double rate)
   {
      super (eName, eAddress, ePhone, eIDNumber, rate);

      hoursWorked = 0;
   }

   //-----------------------------------------------------------------
   //  Adds the specified number of hours to this staff's
   //  accumulated hours.
   //-----------------------------------------------------------------
   public void addHours (int moreHours)
   {
      hoursWorked += moreHours;
   }

   //-----------------------------------------------------------------
   //  Computes and returns the pay for this part time staff.
   //-----------------------------------------------------------------
   public double basicPay()
   {
      double payment = payRate * hoursWorked;

      hoursWorked = 0;

      return payment;
   }

   //-----------------------------------------------------------------
   //  Returns information about this part time staff as a string.
   //-----------------------------------------------------------------
   public String toString()
   {
      String result = super.toString();

      result += "\nCurrent hours: " + hoursWorked;

      return result;
   }
}

The Staff class shown in Listing 7.17 maintains an array of objects that represent individual employees of various kinds. Note that the array is declared to hold StaffMember references, but it is actually filled with objects created from several other classes, such as Executive and Employee. These classes are all descendants of the StaffMember class, so the assignments are valid.
The payday method of the Staff class scans through the list of employees, printing their information and invoking their “pay” methods to determine how much each employee should be paid. The invocation of the “pay” method is polymorphic because each class has its own version of the “pay” method.
The StaffMember class shown in Listing 7.18 is abstract. It does not represent a particular type of employee and is not intended to be instantiated. Rather, it serves as the ancestor of all employee classes and contains information that applies to all employees. Each employee has a name, address, and phone number, so variables to store these values are declared in the StaffMember class and are inherited by all descendants.
The StaffMember class contains a toString method to return the information managed by the StaffMember class. It also contains an abstract method called pay, which takes no parameters and returns a value of type double. At the generic StaffMember level, it would be inappropriate to give a definition for this method. The descendants of StaffMember, however, each provide their own specific definition for pay. By defining pay abstractly in StaffMember, the payday method of Staff can polymorphically pay each employee.
The Volunteer class shown in Listing 7.19 represents a person that is not compensated monetarily for his or her work. We keep track only of a volunteer’s basic information, which is passed into the constructor of Volunteer, which in turn passes it to the StaffMember constructor using the super reference. The “pay” method of Volunteer simply returns a zero pay value. If pay had not been overridden, the Volunteer class would have been considered abstract and could not have been instantiated.
Note that when a volunteer gets “paid” in the payday method of Staff, a simple expression of thanks is printed. In all other situations, where the “pay” value is greater than zero, the payment itself is printed.
The Employee class shown in Listing 7.20 represents an employee that gets paid at a particular rate each pay period. The pay rate, as well as the employee’s social security number, is passed along with the other basic information to the Employee constructor. The basic information is passed to the constructor of StaffMember using the super reference.

Related questions:
1. In what specific cases does inheritance support polymorphism? You can copy and paste the code.
2. How is overriding related to polymorphism?
3. Why is the StaffCrew class in the Hospital example declared as abstract?
4. Why is the pay method declared in the StaffCrew class, given that it is abstract and has nobody at that level?
5. Which “pay” method is invoked by the following line from the payday method of the Staff class?
amount = staffList[count].pay();

Chapter 7: Designing for Inheritance and Interfaces

January 13th, 2017

Interface Hierarchies

  • The concept of inheritance can be applied to interfaces as well as classes.
  • One interface can be derived from another interface.
  • These relationships can form an interface hierarchy, which is similar to a class hierarchy.
  • When a parent interface is used to derive a child interface, the child inherits all abstract methods and constants of the parent.
  • Any class that implements the child interface must implement all of the methods.
  • There are no visibility issues when dealing with inheritance between interfaces (as there are with protected and private members of a class), because all members of an interface are public.
  • Class hierarchies and interface hierarchies do not overlap. That is, an interface cannot be used to derive a class, and a class cannot be used to derive an interface.

Designing for inheritance
▪ Every derivation should be an is-a relationship. The child should be a more specific version of the parent.
▪ Design a class hierarchy to capitalize on reuse, and potential reuse in the future.
▪ As classes and objects are identified in the problem domain, find their commonality. Push common features as high in the class hierarchy as appropriate for consistency and ease of maintenance.
▪ Override methods as appropriate to tailor or change the functionality of a child.
▪ Add new variables to the child class as needed, but don’t shadow (redefine) any inherited variables.
▪ Allow each class to manage its own data. Therefore use the super reference to invoke a parent’s constructor and to call overridden versions of methods if appropriate.
▪ Use interfaces to create a class that serves multiple roles (simulating multiple inheritance).
▪ Design a class hierarchy to fit the needs of the application, with attention to how it may be useful in the future.
▪ Even if there are no current uses for them, override general methods such as toString and equals appropriately in child classes so that the inherited versions don’t cause unintentional problems later.
▪ Use abstract classes to specify a common class interface for the concrete classes lower in the hierarchy.
▪ Choosing which classes and methods to make abstract is an important part of the design process. You should make such choices only after careful consideration. By using abstract classes wisely, you can create flexible, extensible software designs.
▪ Use visibility modifiers carefully to provide the needed access in derived classes without violating encapsulation.
▪ Using the final modifier to restrict inheritance abilities is a key design decision.

Chapter 6: The Selection Sort


Classwork:

Video from Professor Sedgewick on edmodo.com

Videos you can watch at home:



Sorts: The Selection Sort

selectionSort

selectionSortCode

selectionCodeAndVisual

Time efficiency and the Big-Oh notation

Homework:
1. Tell the story of the Selection Sort to someone who knows no computer programming.
2. Show the sequence of changes the selection sort algorithm makes to the following list of numbers:
5 7 1 8 2 4 3

3. Write the code for the Selection Sort in a static function in a tester/driver class, SortTester.java.
Assign random integers in the range of 15 to 35 to an array of 20 “int” elements.
Display the array.
Sort it with the Selection Sort and display it again.

Chapter 6: ArrayLists<E>()

ArrayLists

ArrayLists, type parameter, and for-each loop example

import java.util.ArrayList;

/**
   This bank contains a collection of bank accounts.
*/
public class Bank
{   
   /**
      Constructs a bank with no bank accounts.
   */
   public Bank()
   {
      accounts = new ArrayList();
   }

   /**
      Adds an account to this bank.
      @param a the account to add
   */
   public void addAccount(BankAccount a)
   {
      accounts.add(a);
   }
   
   /**
      Gets the sum of the balances of all accounts in this bank.
      @return the sum of the balances
   */
   public double getTotalBalance()
   {
      double total = 0;
      for (BankAccount a : accounts)
      {
         total = total + a.getBalance();
      }
      return total;
   }

   /**
      Counts the number of bank accounts whose balance is at
      least a given value.
      @param atLeast the balance required to count an account
      @return the number of accounts having least the given balance
   */
   public int count(double atLeast)
   {
      int matches = 0;
      for (BankAccount a : accounts)
      {
         if (a.getBalance() >= atLeast) matches++; // Found a match
      }
      return matches;
   }

   /**
      Finds a bank account with a given number.
      @param accountNumber the number to find
      @return the account with the given number, or null if there
      is no such account
   */
   public BankAccount find(int accountNumber)
   {
      for (BankAccount a : accounts)
      {
         if (a.getAccountNumber() == accountNumber) // Found a match
            return a;
      } 
      return null; // No match in the entire array list
   }

   /**
      Gets the bank account with the largest balance.
      @return the account with the largest balance, or null if the
      bank has no accounts
   */
   public BankAccount getMaximum()
   {
      if (accounts.size() == 0) return null;
      BankAccount largestYet = accounts.get(0);
      for (int i = 1; i < accounts.size(); i++) 
      {
         BankAccount a = accounts.get(i);
         if (a.getBalance() > largestYet.getBalance())
            largestYet = a;
      }
      return largestYet;
   }

   private ArrayList accounts;
}

ArrayLists, type parameter, for-each loop and Iterator another example

/** 
 * mrs.e
 * 12/14/2018
 * 
 * ArrayLists
 * for-each loop
 * Iterator
 * 
 * */

import java.util.ArrayList;
import java.util.Iterator;

public class ArrayListIterator 
{
   public static void main( String[] args )
   {
      // add elements to an ArrayList
      String[] pets = { "Puppy", "Kitten", "Gerbil", "Bunny", "Ferret" };
      ArrayList< String > aList = new ArrayList< String >();      

      for ( String pet : pets )
         aList.add( pet ); // for each loop - don't change the ArrayList   

      // add elements in removePets array to removeList
      String[] removePets = { "Gerbil", "Bunny" };
      ArrayList< String > removeList = new ArrayList< String >();

      for ( String pet : removePets )
         removeList.add( pet ); 

      // print items of the list
      System.out.println( "ArrayList: " );

      for ( int count = 0; count < aList.size(); count++ )
         System.out.printf( "%s ", aList.get( count ) );

      // remove from list the pets contained in removeList
      removePets( aList, removeList );

      // print itmes of the list 
      System.out.println( "\n\nArrayList after calling removePets: " );

      for ( String pet : aList )
         System.out.printf( "%s ", pet );
   } // end main

   // remove pets in collection2 found in collection1
   private static void removePets( ArrayList< String > collection1, 
      ArrayList< String > collection2 )
   {
      // get iterator
      Iterator< String > iterator = collection1.iterator(); 

      // loop while collection has items
      while ( iterator.hasNext() )         
      {
         if ( collection2.contains( iterator.next() ) )
            iterator.remove(); // remove current pet
      } // end while
   } // end method removePets
} // end class ArrayListIterator

indexOf and lastIndexOf example from http://www.dotnetperls.com/arraylist-java

import java.util.ArrayList;

public class Program {
    public static void main(String[] args) {

    ArrayList list = new ArrayList<>();
    list.add(101);
    list.add(100);
    list.add(99);
    list.add(100);
    list.add(99);

    // Search for values.
    int index = list.indexOf(100);
    int lastIndex = list.lastIndexOf(100);
    int notFound = list.indexOf(200);

    // Display results.
    System.out.println(index);     // 1
    System.out.println(lastIndex); // 3
    System.out.println(notFound);  // -1
    }
}

Output

1
3
-1

§ § § § § §

More advanced topics in this link. (Optional)

ListIterator, indexOf, Iterator, List Interface
Screen Shot 2014-12-15 at 9.05.33 PM

[collapse]

Screen Shot 2014-12-11 at 9.19.49 PM

Screen Shot 2014-12-11 at 9.26.39 PM

ArrayList<E>()

Constructs an empty list with an initial capacity of ten.

Screen Shot 2014-12-11 at 9.30.09 PM

boolean add(E obj)
Appends the specified element to the end of this list.

void add(int index, E obj)
Inserts the specified element at the specified position in this list.

E get(int index)
Returns the element at the specified position in this list.

int indexOf(Object obj)
Returns the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element.

boolean isEmpty()
Returns true if this list contains no elements.

int size()
Returns the number of elements in this list.

ListIterator<E> listIterator()

Returns a list iterator over the elements in this list (in proper sequence).

E remove(int index)
Removes the element at the specified position in this list.

boolean remove(Object o)
Removes the first occurrence of the specified element from this list, if it is present.

//********************************************************************
//  DestinysChild.java       Author: Lewis/Loftus/Cocking
//
//  Demonstrates the use of a ArrayList object.
//********************************************************************

import java.util.ArrayList;

public class DestinysChild
{
   //-----------------------------------------------------------------
   //  Stores and modifies a list of band members.
   //-----------------------------------------------------------------
   public static void main (String[] args)
   {
      ArrayList band = new ArrayList();

      band.add ("Michelle");
      band.add ("Kelly");
      band.add ("Beyonce");
      band.add ("Farrah");

      System.out.println (band);

      int location = band.indexOf ("Farrah");
      band.remove (location);

      System.out.println (band);
      System.out.println ("At index 1: " + band.get(1));

      System.out.println (band);
      System.out.println ("Size of the band: " + band.size());
   }
}


[Michelle, Kelly, Beyonce, Farrah]
[Michelle, Kelly, Beyonce]
At index 1: Kelly
[Michelle, Kelly, Beyonce]
Size of the band: 3

Two ways to iterate through the elements of a collection in java:

  1. By Iterator interface.
  2. By for-each loop.
//********************************************************************
//  Recipe.java       Author: Lewis/Loftus/Cocking
//
//  Demonstrates the use of a ListIterator to iterate through the
//  elements of an ArrayList.
//********************************************************************

import java.util.ArrayList;
import java.util.ListIterator;

public class Recipe
{
   //-----------------------------------------------------------------
   //  Stores and then prints a list of ingredients for a recipe.
   //-----------------------------------------------------------------
   public static void main (String[] args)
   {
      ArrayList ingredients = new ArrayList();

      ingredients.add ("flour");
      ingredients.add ("sugar");
      ingredients.add ("cocoa");
      ingredients.add ("oil");
      ingredients.add ("butter");
      ingredients.add ("eggs");
      ingredients.add ("baking soda");

      System.out.println ("To make a chocolate cake, use the following " +
         ingredients.size() + " ingredients:");

      // traversing ArrayList by Iterator
      ListIterator iterator = ingredients.listIterator(); 
      while (iterator.hasNext())
         System.out.println(iterator.next());

      // traversing ArrayList using the "for-each" loop
       for(String obj:ingredients)  
          System.out.println(obj);  

   }
}

To make a chocolate cake, use the following 7 ingredients:
flour
sugar
cocoa
oil
butter
eggs
baking soda

Classwork/Homework:
1. Create a class DataSet of BankAccounts. The constructor creates an ArrayList of BankAccount(s). Write the test class to add, delete and print (use the for-each loop) bank accounts. Your driver should have at least 3 BankAccount objects. Make any changes necessary to have the DataSet ADT implemented with an ArrayList. Also, change the comments to fit the modifications to the it.

DataSet with ArrayList

/**
   Computes the average of a set of data values.
*/
public class DataSet
{
   /**
      Constructs an empty data set with no BankAccount objects.
   */
   public DataSet()
   {
      sum = 0;
      count = 0; // Warning: Is "count" necessary?
      maximum = 0; // Warning: this should not be a numeric type!!
      // create an object of the ArrayList dataSet
   }

   /**
      Adds a BankAccount object to the data set
      @param x a BankAccount object
   */
   public void add(BankAccount bank)
   {
      // add object to ArrayList
      sum = sum + bank.getBalance();
      if (count == 0 || maximum.getBalance() < x.getBalance()) maximum = x;
      count++;
   }

   /**
      Gets the average of the added BankAccount balances.
      @return the average or 0 if no data has been added
   */
   public double getAverage()
   {
      if (count == 0) return 0;
      else return sum / count;  // Warning
   }

   /**
      Gets the largest of the added data. // changes must be made here
      @return the maximum or 0 if no data has been added
   */
   public BankAccount getMaximum()
   {
      return maximum;
   }

   /**
      Prints the balance for each element of the added data in the ArrayList.// Warning
      @return the average or 0 if no data has been added
   */
   public void printDataSet()
   {
     // implement the code to print the elements of the ArrayList datSet. Add more specific comments
     // use the for-each loop
   }

   private double sum;
   private BankAccount maximum;
   private int count;
   private ArrayList dataSet;
}

[collapse]
  1. Create a class Purse (see below) that contains an ArrayList of Coin(s). Write the test class to add, delete, and print coins. Make any changes necessary to have the Purse class implemented with an ArrayList. Also, change the comments to fit the modifications to the ADT.
/**
   A coin with a monetary value.
*/
public class Coin
{
   /**
      Constructs a coin.
      @param aValue the monetary value of the coin.
      @param aName the name of the coin
   */
   public Coin(double aValue, String aName) 
   { 
      value = aValue; 
      name = aName;
   }

   /**
      Gets the coin value.
      @return the value
   */
   public double getValue() 
   {
      return value;
   }

   /**
      Gets the coin name.
      @return the name
   */
   public String getName() 
   {
      return name;
   }

   public boolean equals(Object otherObject)
   {  
      Coin other = (Coin)otherObject;
      return name.equals(other.name) 
         && value == other.value; 
   }

   private double value;
   private String name;
}

Modify the Purse class to be implemented with ArrayList<Coin> and to use a for-each loop.
Implement the following methods in the Purse class:

   /**
      Counts the number of coins in the purse
      @return the number of coins
   */
   public int count()
   {
     
   }

   /**
      Tests if the purse has a coin that matches
      a given coin.
      @param aCoin the coin to match
      @return true if there is a coin equal to aCoin
   */
   public boolean find(Coin aCoin)
   {

   }

   /**
      Counts the number of coins in the purse that match
      a given coin.
      @param aCoin the coin to match
      @return the number of coins equal to aCoin
   */
   public int count(Coin aCoin)
   {

   }

   /**
      Finds the coin with the largest value. 
      (Precondition: The purse is not empty)
      @return a coin with maximum value in this purse
   */
   pulic Coin getMaximum()
   {

   }

NOTE: Use the “for-each” loop in the implementation.

Chapter 6: Telephone Directory

Classwork:
Write a telephone lookup program, TelephoneDirectory_YI.java. Create a class Telephone with two instance fields, number and name. You have the choice of creating your own data or using the data below to create an array of 100 Telephone objects in random order. TelephoneDirectory handles lookups by name and also reverse lookups by phone number. Use a binary search for both lookups. Make sure you include the test/driver class with enough activity to show your work.

Screen Shot 2014-11-25 at 1.35.03 PM

NOTE: create a text file with random data in the following format:

Last name, First name, area code "-" exchange "-" extension

The following java program might help you with “some” of the code you need to create the text data file.

PhoneNumber

/******************************************************************************
* Compilation: javac PhoneNumber.java
* Execution: java PhoneNumber
* Dependencies:
*
* Immutable data type for US phone numbers.
*
******************************************************************************/

import java.util.HashSet;

/**
* The {@code PhoneNumber} class is an immutable data type to encapsulate a
* U.S. phone number with an area @code (3 digits), exchange (3 digits),
* and extension (4 digits).
*

* For additional documentation,
* see Section 1.2 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public final class PhoneNumber {
private final int area; // area @code (3 digits)
private final int exch; // exchange (3 digits)
private final int ext; // extension (4 digits)

/**
* Initializes a new phone number.
*
* @param area the area @code (3 digits)
* @param exch the exchange (3 digits)
* @param ext the extension (4 digits)
*/
public PhoneNumber(int area, int exch, int ext) {
this.area = area;
this.exch = exch;
this.ext = ext;
}

/**
* Compares this phone number to the specified phone number.
*
* @param other the other phone number
* @return {@code true} if this phone number equals {@code other};
* {@code false} otherwise
*/
@Override
public boolean equals(Object other) {
if (other == this) return true;
if (other == null) return false;
if (other.getClass() != this.getClass()) return false;
PhoneNumber that = (PhoneNumber) other;
return (this.area == that.area) && (this.exch == that.exch) && (this.ext == that.ext);
}

/**
* Returns a string representation of this phone number.
*
* @return a string representation of this phone number
*/
@Override
public String toString() {
// 0 for padding with digits with leading 0s
return String.format(“(%03d) %03d-%04d”, area, exch, ext);
}

/**
* Returns an integer hash code for this phone number.
*
* @return an integer hash code for this phone number
*/
@Override
public int hashCode() {
return 31 * (area + 31 * exch) + ext;
}

/**
* Unit tests the {@code PhoneNumber} data type.
*
* @param args the command-line arguments
*/
public static void main(String[] args) {
PhoneNumber a = new PhoneNumber(609, 258, 4455);
PhoneNumber b = new PhoneNumber(609, 876, 5309);
PhoneNumber c = new PhoneNumber(609, 555, 5309);
PhoneNumber d = new PhoneNumber(215, 876, 5309);
PhoneNumber e = new PhoneNumber(609, 876, 5309);
StdOut.println(“a = ” + a);
StdOut.println(“b = ” + b);
StdOut.println(“c = ” + c);
StdOut.println(“d = ” + d);
StdOut.println(“e = ” + e);

HashSet set = new HashSet();
set.add(a);
set.add(b);
set.add(c);
StdOut.println(“Added a, b, and c”);
StdOut.println(“contains a: ” + set.contains(a));
StdOut.println(“contains b: ” + set.contains(b));
StdOut.println(“contains c: ” + set.contains(c));
StdOut.println(“contains d: ” + set.contains(d));
StdOut.println(“contains e: ” + set.contains(e));
StdOut.println(“b == e: ” + (b == e));
StdOut.println(“b.equals(e): ” + (b.equals(e)));
}

}

[collapse]

From Ashwin:
Screen Shot 2015-11-21 at 3.16.27 PM

Chapter 6: ArrayLists – DataSet

DataSet class should look like this:

import java.util.ArrayList; 
/**
   This class computes the average of a set of data values.
*/
public class DataSet
{
   /**
      Constructs an empty data set.
   */
   public DataSet()
   {
      create ArrayList
      /*  write your code here  */
   }

   /**
      Adds a data value to the data set
      @param x a data value
   */
   public void add(double x)
   {
    /*  write your code here  */
   }

   /**
      Gets the average of the added data.
      @return the average or 0 if no data has been added
   */
   public double getAverage()
   {
      /*  write your code here  */
   }

   private ArrayList data;
}

ArrayLists with Generic Types

The type ArraList identifies an array list of bank accounts.

The angle brackets around the BankAccount type tell you that BankAccount is a type parameter.

Use an ArrayList whenever you want to collect objects of type T.

However, you cannot use primitive types as type parameters — there is no ArrayList or ArrayList.

ArrayList accounts = new ArrayList();
accounts.add(new BankAccount(100));
accounts.add(new BankAccount(105));
accounts.add(new BankAccount(102));

An Object of a Wrapper Class

Wrapper objects can be used anywhere that objects are required instead of primitive type values. For example, you can collect a sequence of floating-point numbers in an ArrayList.

Conversion between primitive types and the corresponding wrapper classes is automatic. This process is called auto-boxing (even though auto-wrapping would have been more consistent).

For example, if you assign a number to a Double object, the number is automatically “put into a box”, namely a wrapper object.
Double d = 29.95; // auto-boxing; same as Double d = new Double(29.95);

Wrapper objects are automatically “unboxed” to primitive types.
double x = d; // auto-unboxing; same as double x = d.doubleValue();

ArrayList data = new ArrayList();
data.add(29.95);
double x = data.get(0);

Classwork:
1. Change DestinysChild and Recipe classes to use parameter types.

2. Create a class DataSet of BankAccounts. The constructor creates an ArrayList. Write the test class to add, delete and print bank accounts.

3. Create a class Purse that contains an ArrayList of Coin(s). Write the test class to add, delete, and print coins.

Chapter 6: ArrayList Project

Look in edmodo.com for the project due: (No partners)
Design and implement a class called Card that represents a standard playing card. Each card has a suit and a face value. A Card ADT represents a standard playing card.

Create a class called DeckOfCards that stores 52 objects of the Card class using ArrayList. Include methods to

  • Shuffle the deck. The shuffle method should assume a full deck.
  • Deal a card
  • Report the number of cards left in the deck
  • In addition:

  • Write the method “printForEach” to print all the cards in the deck using the “for-each” loop.
  • Write the method “printIterator” to print all the cards in the deck using the “ListIterator“.
  • Create a driver class with a main method that deals each card from a shuffled deck, printing each card as it is dealt.




  • 🃏