Search code examples
c#classmultiple-constructors

Construction looping through object creation


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CodyGarrettEX3
{
    public class Account
    {
        private long acctNumber;
        protected double balance;
        public Savings SavingsAccount;
        public Checking CheckingAccount;

        public Account()
        {
            this.acctNumber = 1234;
            Savings SavingsAccount = new Savings(acctNumber);
            Checking CheckingAccount = new Checking(acctNumber);
        }

        public Account(long newAcctNo)
        {
            this.acctNumber = newAcctNo;
            Savings SavingsAccount = new Savings(newAcctNo);
            Checking CheckingAccount = new Checking(newAcctNo);
        }

        //Members
        public long AcctNo
        {
            get { return AcctNo; }
            set { AcctNo = value; }
        }

        public double Balance
        {
            get { return balance; }
            set { balance = value; }
        }

        public virtual double Withdrawal(double amount)
        {
            if ((balance - amount) < 0)
            {
                PolicyException insufficientFundsException = new PolicyException("Insufficient Funds To Complete This Transaction");
                throw insufficientFundsException;
            }

            return balance;
        }

        public double Deposit(double amount)
        {
            balance = balance + amount;
            return balance;
        }

    }
}



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CodyGarrettEX3
{
    public class Savings: Account
    {
        private double interestRate;
        private double minBalance;

        public Savings(long newAcctNumber):base(newAcctNumber)
        {
            balance = 0;
            interestRate = 0;
            minBalance = 0;
        }

        //Properties
        public double InterestRate //This is a correctional to ensure that the interest rate is always stored as a decimal for math calculations
        {
            get { return interestRate; }
            set 
            { 
                if (value > 0)
                {
                    value = value / 100;
                }
                interestRate = value;
            }
        }

        public double MinBalance
        {
            get { return minBalance; }
            set { minBalance = value; }
        }

        public override double Withdrawal(double amount)
        {
            if (minBalance > 0)
            {
                if (amount > (balance - minBalance))
                {
                    PolicyException minBalanceException = new PolicyException("Insufficient Funds to Complete This Transaction, Exceeds Account Balance and Minimum Balance of Account");
                    throw minBalanceException;
                }
            }
            else
            {
                if(amount > (balance - amount))
                {
                    PolicyException insufficientFundsException = new PolicyException("Insufficient Funds to Complete This Transaction, Exceeds Account Balance");
                    throw insufficientFundsException;
                }
            }
            return balance;
        }

    }
}

The main issue as it would seem is that upon compilation of the class that manipulates my parent Which is the Account Class is that I get a really odd loop that just goes from the Account Constructor to the Savings Constructor rapidly and then causes a stack overflow.

This happens after the execution of "Account BankAccount = new Account(9999);" in my program testing class.

Thank you so much for your help everyone! I'm really struggling to figure out what is the cause here.

Also, side note I have the constructor built that way due to a requirement in an assignment that mandates we have to have the acctNumber variable pass into the object before it can be created. Even if the object doesn't use the value. However, if this is not possible I am open to anything really.


Solution

  • The loop isn't so odd. In Savings, you are inheriting from Account. The constructor of Savings also calls the constructor of Account.

    The constructor of Account creates a new "Savings" object. The constructor of this new savings object wants to pass data to the constructor of Accounts, which wants to create a new Savings object. Rince and repeat. This will go on and on and on.

    It looks like a code smell that the base class (Account) creates (and knows about) the inheriting classes (like Savings).

    Edit: I don't know the details of your requirements, but as I'm looking at this the design is not appropriate for your problem.

    You've got your bank account, and this bank account can be a Savings-type account.

    class Account
    {
       protected int _accNr;
    
       public Account()
       {
          _accnr = 1234;
       }       
    
       public Account(int accNr)
       {
          _accNr = accNr;
          // only do basic 'account' stuff
       }
    }
    
    class Savings : Account
    {
       public Savings() : base()
       {
          // do other stuff
       }
    
       public Savings(int accNr) : base(accNr)
       {
          // do other stuff
       }
    }
    

    Now, I've only set up the constructors and nothing else. Point is that now you can either create a Savings class with, or, without an account nr by calling:

    Account a = new Savings();
    

    or

    Account b = new Savings(9999);
    

    Now, responsabilities are split between account- and savings-classes. The Account class doesn't want to know about inheriting classes and their responsibilities. Through polymorphism we can create Accounts of type 'Savings', but you could also ignore that and do Savings a = new Savings(9999).