Author Archives: graceliana@gmail.com

Chapter 7: Pet Shop v1 – Final Version

Before turning in your work, review that you satisfied the requirements discussed in class:

1. DO NOT VIOLATE ENCAPSULATION
2. Use INHERITANCE CONCEPTS to re-use code and functionality.

Specifications:
You will create only one animal class and two of your classmates will share one of their own each for you to have a complete Pet Shop application.

The sample test below is incomplete and you need to add whatever os necessary to make it work.

…
PetSet myPetShop = new PetSet();
        
Animal tweety = new Bird(45.00, "I am a bird");
Animal duffy = new Bird(5.00, "I am a bird");
Animal nemo = new Fish(62.00, "I am a fish"); 
Animal bear = new Dog(1100.00, "I am a dog");
…
…
myPetShop.add(tweety);
myPetShop.add(duffy);
myPetShop.add(nemo);
myPetShop.add(bear);
…
System.out.println(myPetShop);


Chapter 7: Abstract Class Exercise

Happy New Year!!
new-year-gif
Welcome back!

Classwork:

“Abstract Classes” already posted.

Students presentation/discussions about the following assignments:

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

2. Create a class Purse that contains an ArrayList of Coin(s). Write the test class to add, delete, and print coins.
Modify the Purse class to be implemented with ArrayList class 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
   */
   Coin getMaximum()
   {

   }

Homework:
Self-review questions 7.1 through 7.8
1 Question on edmodo.com

Chapter 7: Inheritance – Abstract Classes

Abstract Classes

  • It represents a concept on which other classes can build their definitions.An abstract class cannot be instantiated.
  • A class derived from an abstract parent must override all of its parent’s abstract methods, or the derived class will also be considered abstract.
  • An abstract class is similar to an interface in some ways.
  • However, unlike interfaces, an abstract class can contain methods that are not abstract.
  • An abstract class can also contain data declarations other than constants.
  • A class is declared as abstract by including the abstract modifier in the class header.
  • Any class that contains one or more abstract methods must be declared as abstract.
  • In abstract classes (unlike interfaces), the abstract modifier must be applied to each abstract method.
  • A class declared as abstract does not have to contain abstract methods.
  • Abstract classes serve as placeholders in a class hierarchy.
  • If a child of an abstract class does not give a definition for every abstract method that it inherits from its parent, then the child class is also considered abstract.
  • Note that it would be a contradiction for an abstract method to be modified as final or static.
  • Because abstract methods have no implementation, an abstract static method would make no sense.

Homework:
Read pages 382 through 419 and do exercises MC 7.1 through 7.10 and SA 7.3 and 7.4

giphy

All source: Java Software Solutions by Lewis, Loftus and Cocking

Chapter 7: Inheritance/Interface – Symbiopoly

January 9th, 2018

Classwork/Homework:

Design and implement a new ADT called Symbiopoly. A Symbiopoly object has a symbiotic relationship with a different ADT object. The purpose of this assignment is to work with an interface, Countable and appreciate its powerful feature: different objects share common members. This application is an example of polymorphic behavior that takes place during late binding.

Screen Shot 2015-11-08 at 11.27.08 PM

The outline of the Symbiopoly ADT is very similar to the DataSet ADT.
Below is an example of the minimum required for this assignment’s driver. You need to write the code for the ADTs used in this application.

/*
 * @GE
 * @11/6/14
 * @revisions 11/2/15, 11/26/16, 1/9/18
 * A symbiotic system with different "countable" objects.
 * In this symbiotic system there are "complex" (e.g. clownfish) 
 * and "simple" organisms (e.g. green algae)
*/
public class Symbiopoly
{
   private int totalCount;
   private int symbioCount;
   private Countable mostSymbioticObjects;

   /**
      Constructs an empty symbiotic objects system.
   */
   public Symbiopoly()
   {
      // total number of symbiotic objects in the whole symbiotic system 
      // (e.g. # of anemones + # of clownfish + # of green algae organisms)
      totalCount = 0;  
      
     // the symbiotic object with the most complex objects  
     // (e.g. the anemone with most # of clownfish + # of green algae organisms  
      mostSymbioticObjects = null;      
                                    
   }
...
    // public void add( what????);  // only one add method can be implemented - NO OVERLOADING
... 
}

An example of a test class:

/**
   This program tests the Symbiopoly class by creating a reef
   and adding sea life to it. 
*/
public class CoralReefDriver
{
   public static void main(String[] args)
   {
      // create sea life for the coral reef 

        Anemone cnidarians = new Anemone("cnidarians"); // courtesy from Jason Shao
        Anemone condy = new Anemone("condy");           // courtesy from Jason Shao
        Anemone ritteri = new Anemone("ritteri");       // courtesy from Jason Shao

        Clownfish glowy = new Clownfish("glowy");       // courtesy from Jason Shao
        Clownfish bashful = new Clownfish("bashful");   // courtesy from Jason Shao
        Clownfish flowy = new Clownfish("flowy");       // courtesy from Jason Shao

        GreenAlgae gAlgeaS = new GreenAlgae("gAlgeaS"); // courtesy from Jason Shao
        GreenAlgae gAlgeaN = new GreenAlgae("gAlgeaN"); // courtesy from Jason Shao
        GreenAlgae gAlgeaE = new GreenAlgae("gAlgeaE"); // courtesy from Jason Shao
        GreenAlgae gAlgeaW = new GreenAlgae("gAlgeaW"); // courtesy from Jason Shao
      
      // add friends to an anemone
      cnidarians.add(glowy);
      cnidarians.add(bashful);
      cnidarians.add(gAlgeaS);
      cnidarians.add(gAlgeaW);
      
      // create a reef 
      Symbiopoly redReef = new Symbiopoly();
      
      // add sea life to the reef
      redReef.add(cnidarians);
      redReef.add(gAlgaeE);
      redReef.add(flowy);



      // print reef with most sea life
      System.out.println("Number of all symbiotic friends " +
          redReef.getTotalCount());
      // get the number of symbiotic friends
      System.out.println("Number of friends in this object " + cnidarians.getSymbioCount());
      // get the animal with the most sea life
      Countable mostSeaLife = redReef.mostSymbioticObjects();
      // get the animal's name
      System.out.println("The species with the most friends: " +   
          mostSeaLife.getName());
     
   }
}

Output samples:
// @author: MS
// OUTPUT:
// Number of symbiotic friends 7
// Number of friends in this object 4
// The species with the most friends: Anemone

/**
 * ee
 * Driver for Symbiopoly 
 * @author emily
 * 
 * output:
 * Number of symbiotic friends 7
 * Number of friends in this object 4
 * The species with the most friends: Cnidarians
 *
 */

Screen Shot 2015-11-08 at 11.27.21 PM

giant-green-anemone

Natural History

This green plantlike creature is actually an animal with algae plants living inside it. In this symbiotic relationship, the algae gain protection from snails and other grazers and don’t have to compete for living space, while the anemones gain extra nourishment from the algae in their guts. Contrary to popular opinion, this anemone’s green color is produced by the animal itself, not the algae that it eats.

Use the Countable interface:


/**
 * Interface Countable: use the "implements" keyword to indicate that a class 
 * implements an interface type. Unlike a class, an interface type provides no implementation
 * @GE
 * @11/6/14
 * @revisions 11/2/15, 11/26/16
 */

/**
   Describes any class whose objects can be counted.
*/
public interface Countable
{
   /**
      Computes the number of object there are in a host.
      @return the count 
   */
   int getSymbioCount();
   
   // count of symbiotic objects "this" object has(e.g. # of clownfish in each
   // anemones, # of green algae organisms in each anemones)       
   int symbioCount;  // it is "public"!!!!! so it can be accessed without getSymbioCount();     
   
   /**
    * animal's name
    */
   String getName();
}

Chapter 7: Inheritance Method behavior

Inheritance
Method behavior

Base and Derived classes are simple classes with one constructor and two methods

Constructors and Methods

Study the code and the output from the driver class. Make conclusions and post them in edmodo.com

Constructor behavior
Basic Inheritance Constructors Behavior

Study the code and the output from the driver class. Make conclusions and post them in edmodo.com

Classwork:
Implement an application similar to the one above to show:

  1. Calls to constructors with and without “super”
  2. Calls to methods with and without “super”
  3. Polymorphism – late binding
  4. Do not forget to keep your code well documented with clear explanations

Assignments:
Self-Review 7.1 through 7.8
Programming Project 7.5

Visit edmodo.com

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