1
votes

I have been provided with a Superclass called Account with constructor to initialize the balance, and methods to deposit, and withdraw balance, with the balance being declared private. (I cannot add or change any methods or variables in this class at all)

Then, I created a subclass called SavingsAccount with a constructor that accepts a initial balance. If the initial balance is negative, then the account should be initialized with a balance of 0. Also, it contains two over-ridden methods, deposit and withdraw, which checks the amount being deposited and withdrawn to see if it is possible or not. Here's the code that I've been provided (Account) and that I've written (SavingsAccount).

I tried calling the super() inside a if-else conditional, but Java gives an error that super()call has to be the first line of the constructor. So, how do I get around this? Also, since I don't have a setBalance() method in the provided Account class, how can I set the balance from my deposit and withdraw methods in my SavingsAccount class?

Account.Java (Provided for testing, and cannot modify)

public class Account 
{
  private double balance;

    // Constructor to initialise balance
    public Account( double amount )
    {
            balance = amount;
    }

    // Overloaded constructor for empty balance
    public Account()
    {
            this(0.0);
    }

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

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

    public double getBalance()
    {
            return balance;
    }
}  

SavingsAccount.java (Written by me)

public class SavingsAccount extends Account
{
   private int overDraftCount = 0;
   public SafeAccount(double initial_balance)
   {
      if(initial_balance <0)
      {
       super(0.00);
      }
      else
      {
       super(initial_balance);
      }
    }

   @Override
   public void deposit(double amount)
   {
    if(amount < 0)
   {
      ??? = getBalance(); 
   }
    else
   {
      ??? = getBalance()+ amount;
   }
  }
  @Override
  public void withdraw(double amount)
  {
    if(amount < getBalance())
    {
     overDraftCount++;
     ??? = getBalance();
    }

    else
    {
      ??? = getBalance() - amount;
     }
   }

  public int overdraftAttempts()
  {
     return overDraftCount;
  }
 }
4
So, how do I get around this? You don't. Also, since I don't have a setBalance() method in the provided Account class, how can I set the balance from my deposit and withdraw methods in my SavingsAccount class? You can't. Subclasses cannot access their parent's private members (at least not without reflection, and that isn't a good idea for this). Why can't you modify Account?Elliott Frisch
Well, its provided to me by my instructor, and I'll have to create the subclass based on the provided class (Account), without making any changes to the provided one.cfreq744

4 Answers

4
votes

You can change your constructor to use the ternary operator:

public SafeAccount(double initial_balance) {
  super(initial_balance < 0 ? 0.00 : initial_balance);
}

Regarding your second point you will have to use the existing methods to withdraw or deposit savings from/to the account like this:

@Override
public void deposit(double amount) {
  if(amount > 0) {
    super.deposit(amount);
  }
}
2
votes

In this case, it can simply be solved using

public SafeAccount(double initialBalance) {
    super(initialBalance < 0 ? 0.0 : initialBalance));
}

You could also call a static method returning the correct initial balance. Or you could use a factory method instead of a constructor:

private SafeAccount(double initialBalance) {
    super(initialBalance);
}

public static SafeAccount createSafeAccount(double initialBalance) {
    if (initialBalance < 0) {
        return new SafeAccount(0.0);
    }
    else {
        return new SafeAccount(initialBalance);
    }
}

Note that ignoring the argument value that way is most of the time a bad idea. Passing a negative initial balance doesn't make sense, and is thus the sign of a bug. It should thus be signalled by throwing an exception, instead of transforming it to 0.0 and hide the bug, probably thus causing a new bug, even more nasty and harder to diagnose.

Regarding your second question, I don't really see where the problem is. You just need to delegate to the super method:

@Override
public void deposit(double amount) {
    if (amount < 0) {
        throw new IllegalArgumentException("amount should be positive");
    }
    else {
        super.deposit(amount);
    }
}
1
votes

If I correctly understood, you want to make an Account that can't be negative.

So for the constructor, you just have to use a ternary operator:

    public SafeAccount(double initialBalance) {
        super(initialBalance < 0 ? 0 : initialBalance);
    }

And for deposit/withdraw, you can call Account's method using super as well:

    @Override
    public void deposit(double amount) {
        if (amount > 0) {
            super.deposit(amount);
        }
    }

    @Override
    public void withdraw(double amount) {
        if (amount > getBalance()) {
            overDraftCount++;
            // if you want to set to 0.00
            super.withdraw(getBalance());
        } else {
            super.withdraw(amount);
        }
    }

So, your final class should be like this:

public class SafeAccount extends Account {

    private int overDraftCount = 0;

    public SafeAccount(double initialBalance) {
        super(initialBalance < 0 ? 0 : initialBalance);
    }

    @Override
    public void deposit(double amount) {
        if (amount > 0) {
            super.deposit(amount);
        }
    }

    @Override
    public void withdraw(double amount) {
        if (amount > getBalance()) {
            overDraftCount++;
            // if you want to set to 0.00
            super.withdraw(getBalance());
        } else {
            super.withdraw(amount);
        }
    }

    public int overdraftAttempts() {
        return overDraftCount;
    }
}

Note: your code doesn't respect java code conventions, maybe you should take a look at them (google java code conventions, you'll find).

1
votes

Your constructor of SavingsAccount can't work, because the first line of your own constructor must be the super-call, otherwise you will get a compile error. You can achieve your desired result by do something like this:

public SavingsAccount(double initial_balance) {
    super(getAdjustedInitialBalance(initial_balance));
}

private static double getAdjustedInitialBalance(double val) {
    return val < 0 ? 0 : val;
}

Of course the trinary operator can be placed inside the super-call directly as parameter but I find my way more readable since it's explaining the logic by meaningful methodnames.

The other methods can just call each other in case of negative values:

public void withdraw(double amount) {
    if (amount < 0) {
        deposit(-amount);
        return;
    }
    if (amount < getBalance()) {
        overDraftCount++;
        return;
    }
    super.withdraw(amount);
}

public void deposit(double amount) {
    if (amount < 0) {
        withdraw(-amount);
        return;
    }
    super.deposit(amount);
}

So, the answer to your original question is "you can't" (well technically there is a way but you don't do that until you really have to, so I won't show it to you ;-) " and you shouldn't". You use the methods that are publicly available and call them.

Hope that helps with your homework (at least it looks like one)