Review:    What happens when NewClass inherits from SomeClass

The NewClass inherits (= receives) all normal members from its superclass:

All inherited members are now defined inside NewClass and you can use the public members directly

Review:    an overriding method will overshadow its inherited method

When you override an inherited method, a method call will invoke the overriding method by default:

Note:   overriding an inherited method does not change the method inside the super class !

Review:   calling an overridden method from within the subclass

You can invoke an overridden method from within a subclass method using super.methodName(...)

Important note:   there are situations where you must use an overridden method --- next !

Example showing the need to use super to invoke a overridded method

Consider the basic BankAccount class to store information on bank accounts:

public class SavingsAccount
       extends BankAccount
{   
    private final static int MAXNUMFREE = 3;
    private final static double PENALTY = 1.0;  

    private int numWithdrawals;
                                     
    public SavingsAccount(double x)
    {
        super(x);
    }

    public void withdraw(double amount)
    {
        super.withdraw(amount);

	numWithdrawals++;
	if ( numWithdrawals > MAXNUMFREE )
	    super.withdraw(PENALTY);
    }

    public void monthlyReset()
    {
        numWithdrawals = 0;
    }
}   
public class BankAccount
{
    private double balance;

    public BankAccount(double x)
    {
        balance = x;
    }

    public double getBalance()
    {
        return balance;
    }
    
    public void deposit(double amount)
    {
        balance = balance + amount;
    }
    
    public void withdraw(double amount) 
    {
        balance = balance - amount;
    }
}  



The BankAccount support the basic operations: getBalance(), deposit() and withdraw()

Example showing the need to use super to invoke a overridded method

The bank also has a special SavingsAccount specially for people who want to save money:

public class SavingsAccount
       extends BankAccount
{   
    private double interestRate = 0.05;
    private final static int MAXNUMFREE = 3;
    private final static double PENALTY = 1.0;  
    private int numWithdrawals;
                                     
    public SavingsAccount(double x)
    {
        super(x);
    }

    public void withdraw(double amount)
    {
        super.withdraw(amount);

	numWithdrawals++;
	if ( numWithdrawals > MAXNUMFREE )
	    super.withdraw(PENALTY);
    }

    public void addInterest()
    {
        balance += interestRate/12*balance; ???
    }
} 
public class BankAccount
{
    private double balance;

    public BankAccount(double x)
    {
        balance = x;
    }

    public double getBalance()
    {
        return balance;
    }
    
    public void deposit(double amount)
    {
        balance = balance + amount;
    }
    
    public void withdraw(double amount) 
    {
        balance = balance - amount;
    }
}  



The addInterest() method is used to accrue interest to a SavingAccount.... do you see any problem ???

Example showing the need to use super to invoke a overridded method

The balance member variable is private, so code written in SavingAccount class can not access it:

public class SavingsAccount
       extends BankAccount
{   
    private double interestRate = 0.05;
    private final static int MAXNUMFREE = 3;
    private final static double PENALTY = 1.0;  
    private int numWithdrawals;
                                     
    public SavingsAccount(double x)
    {
        super(x);
    }

    public void withdraw(double amount)
    {
        super.withdraw(amount);

	numWithdrawals++;
	if ( numWithdrawals > MAXNUMFREE )
	    super.withdraw(PENALTY);
    }

    public void addInterest()
    {
        balance += interestRate/12*balance; ???
    }   private                    private
} 
public class BankAccount
{
    private double balance;

    public BankAccount(double x)
    {
        balance = x;
    }

    public double getBalance()
    {
        return balance;
    }
    
    public void deposit(double amount)
    {
        balance = balance + amount;
    }
    
    public void withdraw(double amount) 
    {
        balance = balance - amount;
    }
}  



Question:   how can we add the interest to a SavingAccount ??

Example showing the need to use super to invoke a overridded method

We can use getBalance() and deposit(...) to add the accrued interest to a SavingAccount:

public class SavingsAccount
       extends BankAccount
{   
    private double interestRate = 0.05;
    private final static int MAXNUMFREE = 3;
    private final static double PENALTY = 1.0;  
    private int numWithdrawals;
                                     
    public SavingsAccount(double x)
    {
        super(x);
    }

    public void withdraw(double amount)
    {
        super.withdraw(amount);

	numWithdrawals++;
	if ( numWithdrawals > MAXNUMFREE )
	    super.withdraw(PENALTY);
    }

    public void addInterest()
    {
        deposit(interestRate/12*getBalance());
    }
} 
public class BankAccount
{
    private double balance;

    public BankAccount(double x)
    {
        balance = x;
    }

    public double getBalance()
    {
        return balance;
    }
    
    public void deposit(double amount)
    {
        balance = balance + amount;
    }
    
    public void withdraw(double amount) 
    {
        balance = balance - amount;
    }
}  



Note:   deposit( ) and getBalance( ) are not overridden and can access private members in BankAccount

Example showing the need to use super to invoke a overridded method

The bank discourage frequent withdrawal from a SavingsAccount and will allow 3 free withdrawals per month:

public class SavingsAccount
       extends BankAccount
{   
    private double interestRate = 0.05;
    private final static int MAXNUMFREE = 3;
    private final static double PENALTY = 1.0;  
    private int numWithdrawals;
                                     
    public SavingsAccount(double x)
    {
        super(x);
    }

    // Reset # withdrawal at end of month
    public void resetWithdrawals()
    {
        numWithdrawals = 0;
    }
    I will omit this method
    to make space...       


    public void addInterest()
    {
        deposit(interestRate/12*getBalance());
    }
} 
public class BankAccount
{
    private double balance;

    public BankAccount(double x)
    {
        balance = x;
    }

    public double getBalance()
    {
        return balance;
    }
    
    public void deposit(double amount)
    {
        balance = balance + amount;
    }
    
    public void withdraw(double amount) 
    {
        balance = balance - amount;
    }
}  



After the 3 free withdrawals, each additional withdrawal will incur a $1.00 penalty

Example showing the need to use super to invoke a overridded method

The inherited withdraw( ) method does not penalize and is inadequate and must be overridded:

public class SavingsAccount
       extends BankAccount
{   
    private double interestRate = 0.05;
    private final static int MAXNUMFREE = 3;
    private final static double PENALTY = 1.0;  
    private int numWithdrawals;
                                     
    public SavingsAccount(double x)
    {
        super(x);
    }

    public void withdraw(double amount)
    {
        super.withdraw(amount);

	numWithdrawals++;
	if ( numWithdrawals > MAXNUMFREE )
	    super.withdraw(PENALTY);
    }

    public void addInterest()
    {
        deposit(interestRate/12*getBalance());
    }
} 
public class BankAccount
{
    private double balance;

    public BankAccount(double x)
    {
        balance = x;
    }

    public double getBalance()
    {
        return balance;
    }
    
    public void deposit(double amount)
    {
        balance = balance + amount;
    }
    
    public void withdraw(double amount) 
    {
        balance = balance - amount;
    }
}  



Comment:   I will access the balance variable directly - we will fix it later

Example showing the need to use super to invoke a overridded method

When we withdraw from a SavingsAccount, we first perform the withdrawal:

public class SavingsAccount
       extends BankAccount
{   
    private double interestRate = 0.05;
    private final static int MAXNUMFREE = 3;
    private final static double PENALTY = 1.0;  
    private int numWithdrawals;
                                     
    public SavingsAccount(double x)
    {
        super(x);
    }

    public void withdraw(double amount)
    {
        balance = balance - amount;

	numWithdrawals++;
	if ( numWithdrawals > MAXNUMFREE )
	    super.withdraw(PENALTY);
    }

    public void addInterest()
    {
        deposit(interestRate/12*getBalance());
    }
} 
public class BankAccount
{
    private double balance;

    public BankAccount(double x)
    {
        balance = x;
    }

    public double getBalance()
    {
        return balance;
    }
    
    public void deposit(double amount)
    {
        balance = balance + amount;
    }
    
    public void withdraw(double amount) 
    {
        balance = balance - amount;
    }
}  



Next, we must keep track of the number of withdrawals made...

Example showing the need to use super to invoke a overridded method

We use the variable numWithdrawals to keep track of the number of withdrawals made:

public class SavingsAccount
       extends BankAccount
{   
    private double interestRate = 0.05;
    private final static int MAXNUMFREE = 3;
    private final static double PENALTY = 1.0;  
    private int numWithdrawals;
                               
    public SavingsAccount(double x)
    {
        super(x);
    }

    public void withdraw(double amount)
    {
        balance = balance - amount;

	numWithdrawals++;
	if ( numWithdrawals > MAXNUMFREE )
	    super.withdraw(PENALTY);
    }

    public void addInterest()
    {
        deposit(interestRate/12*getBalance());
    }
} 
public class BankAccount
{
    private double balance;

    public BankAccount(double x)
    {
        balance = x;
    }

    public double getBalance()
    {
        return balance;
    }
    
    public void deposit(double amount)
    {
        balance = balance + amount;
    }
    
    public void withdraw(double amount) 
    {
        balance = balance - amount;
    }
}  



Finally, we check for penalties...

Example showing the need to use super to invoke a overridded method

We deduct PENALTY when the number of withdrawals exceeds the # free withdrawals:

public class SavingsAccount
       extends BankAccount
{   
    private double interestRate = 0.05;
    private final static int MAXNUMFREE = 3;
    private final static double PENALTY = 1.0;  
    private int numWithdrawals;
                               
    public SavingsAccount(double x)
    {
        super(x);
    }

    public void withdraw(double amount)
    {
        balance = balance - amount;

	numWithdrawals++;
	if ( numWithdrawals > MAXNUMFREE )
	    balance -= PENALTY; // penalty
    }

    public void addInterest()
    {
        deposit(interestRate/12*getBalance());
    }
} 
public class BankAccount
{
    private double balance;

    public BankAccount(double x)
    {
        balance = x;
    }

    public double getBalance()
    {
        return balance;
    }
    
    public void deposit(double amount)
    {
        balance = balance + amount;
    }
    
    public void withdraw(double amount) 
    {
        balance = balance - amount;
    }
}  



Question:   how can we subtract from the private variable balance ???

Example showing the need to use super to invoke a overridded method

We must use the withdraw( ) method inside the super class (i.e." super.withdraw( ) ):

public class SavingsAccount
       extends BankAccount
{   
    private double interestRate = 0.05;
    private final static int MAXNUMFREE = 3;
    private final static double PENALTY = 1.0;  
    private int numWithdrawals;
                               
    public SavingsAccount(double x)
    {
        super(x);
    }

    public void withdraw(double amount)
    {
        super.withdraw(amount);

	numWithdrawals++;
	if ( numWithdrawals > MAXNUMFREE )
	    super.withdraw(PENALTY); // penalty
    }

    public void addInterest()
    {
        deposit(interestRate/12*getBalance());
    }
} 
public class BankAccount
{
    private double balance;

    public BankAccount(double x)
    {
        balance = x;
    }

    public double getBalance()
    {
        return balance;
    }
    
    public void deposit(double amount)
    {
        balance = balance + amount;
    }
    
    public void withdraw(double amount) 
    {
        balance = balance - amount;
    }
}  



I have a test program in the next slide (and a demo....)

Test program for SavingsAccount

public class myProg
{
    public static void main(String[] args)
    {
        SavingsAccount a = new SavingsAccount(100);
        
        a.withdraw(10); 
        System.out.println(a.getBalance());  // 90
        a.withdraw(10); 
        System.out.println(a.getBalance());  // 80
        a.withdraw(10); 
        System.out.println(a.getBalance());  // 70
        a.withdraw(10); 
        System.out.println(a.getBalance());  // 59 ! ($1 penalty)
    }
}
  

DEMO: 04-inheritance/10-saving

  Quiz  

What will happen if we did not use super to invoke withdraw( ):

public class SavingsAccount
       extends BankAccount
{   
    private double interestRate = 0.05;
    private final static int MAXNUMFREE = 3;
    private final static double PENALTY = 1.0;  
    private int numWithdrawals;
                               
    public SavingsAccount(double x)
    {
        super(x);
    }

    public void withdraw(double amount)
    {
        super.withdraw(amount);

	numWithdrawals++;
	if ( numWithdrawals > MAXNUMFREE )
	    super.withdraw(PENALTY); // penalty
    }

    public void addInterest()
    {
        deposit(interestRate/12*getBalance());
    }
} 
public class BankAccount
{
    private double balance;

    public BankAccount(double x)
    {
        balance = x;
    }

    public double getBalance()
    {
        return balance;
    }
    
    public void deposit(double amount)
    {
        balance = balance + amount;
    }
    
    public void withdraw(double amount) 
    {
        balance = balance - amount;
    }
}  



  Quiz  

The withdraw method is recursive and will crash:

public class SavingsAccount
       extends BankAccount
{   
    private double interestRate = 0.05;
    private final static int MAXNUMFREE = 3;
    private final static double PENALTY = 1.0;  
    private int numWithdrawals;
                               
    public SavingsAccount(double x)
    {
        super(x);
    }

    public void withdraw(double amount)
    {
        withdraw(amount);   // Recursion !

	numWithdrawals++;
	if ( numWithdrawals > MAXNUMFREE )
	    withdraw(PENALTY); // penalty
    }

    public void addInterest()
    {
        deposit(interestRate/12*getBalance());
    }
} 
public class BankAccount
{
    private double balance;

    public BankAccount(double x)
    {
        balance = x;
    }

    public double getBalance()
    {
        return balance;
    }
    
    public void deposit(double amount)
    {
        balance = balance + amount;
    }
    
    public void withdraw(double amount) 
    {
        balance = balance - amount;
    }
}  



Use: 04-inheritance/10-saving to demo...