How to use both sub-classes in C#

BenTam 1,581 Reputation points
2020-12-04T09:14:13.203+00:00

Hi All,

I want to how to use both subclasses "InterestEarningAccount" and "LineOfCreditAccount" in the same program.

TIA

sub class InterestEarningAccount

using System;
namespace Inherit3

{
    public class InterestEarningAccount : BankAccount
    {
        public InterestEarningAccount(string name, decimal initialBalance) : base(name, initialBalance) { }
        public override void PerformMonthEndTransactions()
        {
            if (Balance > 500m)
            {
                var interest = Balance * 0.05m;
                MakeDeposit(interest, DateTime.Now, "apply monthly interest");
            }
        }
    }
}

sub-class LineOfCreditAccount

using System;

namespace Inherit3
{
class LineOfCreditAccount : BankAccount
{
public LineOfCreditAccount(string name, decimal initialBalance, decimal creditLimit) : base(name, initialBalance, -creditLimit) { }
public override void PerformMonthEndTransactions()
{
if (Balance < 0)
{
// Negate the balance to get a positive interest charge:
var interest = -Balance * 0.07m;
MakeWithdrawal(interest, DateTime.Now, "Charge monthly interest");
}
}
protected override Transaction? CheckWithdrawalLimit(bool isOverdrawn) =>
isOverdrawn
? new Transaction(-20, DateTime.Now, "Apply overdraft fee")
: default;
}
}

Parent Class "Inheritance.cs"

using System;
using System.Collections.Generic;

namespace Inherit3
{
    public class Transaction
    {
        public decimal Amount { get; }
        public DateTime Date { get; }
        public string Notes { get; }
        public Transaction(decimal amount, DateTime date, string note)
        {
            this.Amount = amount;
            this.Date = date;
            this.Notes = note;
        }
    }
    public class BankAccount
    {
        public string Report { get; set; }
        public decimal InitialBalance { get; set; }
        public string Number { get; }
        public string Owner { get; set; }
        public decimal Balance
        {
            get
            {
                decimal balance = InitialBalance;
                foreach (var item in allTransactions)
                {
                    balance += item.Amount;
                }
                return balance;
            }
        }
        private List<Transaction> allTransactions = new List<Transaction>();

        private static int accountNumberSeed = 1234567890;
        public virtual void PerformMonthEndTransactions() { }
        private readonly decimal minimumBalance;
        public BankAccount(string name, decimal initialBalance) : this(name, initialBalance, 0) { }
        public BankAccount(string name, decimal initialBalance, decimal minimumBalance)
        {
            this.Number = accountNumberSeed.ToString();
            accountNumberSeed++;
            this.Owner = name;
            this.minimumBalance = minimumBalance;
            if (initialBalance > 0)
                MakeDeposit(initialBalance, DateTime.Now, "Initial balance");
        }
        public void MakeDeposit(decimal amount, DateTime date, string note)
        {
            if (amount <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(amount), "Amount of deposit must be positive");
            }
            var deposit = new Transaction(amount, date, note);
            allTransactions.Add(deposit);
        }

        public void MakeWithdrawal(decimal amount, DateTime date, string note)
        {
            if (amount <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(amount), "Amount of withdrawal must be positive");
            }
            var overdraftTransaction = CheckWithdrawalLimit(Balance - amount < minimumBalance);
            var withdrawal = new Transaction(-amount, date, note);
            allTransactions.Add(withdrawal);
            if (overdraftTransaction != null)
                allTransactions.Add(overdraftTransaction);
        }
        protected virtual Transaction? CheckWithdrawalLimit(bool isOverdrawn)
        {
            if (isOverdrawn)
            {
                throw new InvalidOperationException("Not sufficient funds for this withdrawal");
            }
            else
            {
                return default;
            }
        }
        public string GetAccountHistory()
        {
            var report = new System.Text.StringBuilder();
            decimal balance = 0;
            report.AppendLine("Date\t\tAmount\tBalance\tNote");
            foreach (var item in allTransactions)
            {
                balance += item.Amount;
                report.AppendLine($"{item.Date.ToShortDateString()}\t{item.Amount}\t{balance}\t{item.Notes}");
            }
            this.Report += report.ToString();
            return this.Report;

        }
    }
}

Parent Class Inheritance.cs

using System;

namespace Inherit3
{
    class Program
    {
        static void Main(string[] args)
        {
            var lineOfCredit = new LineOfCreditAccount("line of credit", 0, 2000);
            // How much is too much to borrow?
            lineOfCredit.MakeWithdrawal(1000m, DateTime.Now, "Take out monthly advance");
            lineOfCredit.MakeDeposit(50m, DateTime.Now, "Pay back small amount");
            lineOfCredit.MakeWithdrawal(5000m, DateTime.Now, "Emergency funds for repairs");
            lineOfCredit.MakeDeposit(150m, DateTime.Now, "Partial restoration on repairs");
            lineOfCredit.PerformMonthEndTransactions();
            //var interestEarning = new InterestEarningAccount ("interest earning", 0, )
            Console.WriteLine(lineOfCredit.GetAccountHistory());
        }
    }
}
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,364 questions
0 comments No comments
{count} votes

Accepted answer
  1. Bonnie DeWitt 811 Reputation points
    2020-12-05T20:45:06.1+00:00

    Hi Ben,

    Yes, the parent class will set the Balance to 0, but the BankAccount class is nothing but a class that both the LineOfCreditAccount and the InterestEarningAccount are based on, or subclassed from, or derived from, whichever terminology you prefer.

    Each is its own instance of their class and the two instances have nothing to do with each other. They are simply derived from the same base class.

    So, after instantiating the new InterestEarningAccount, it sounds like maybe you want to something like this?

    var interestEarning = new InterestEarningAccount ("interest earning", 0);
    interestEarning.InitialBalance = lineOfCredit.Balance;
    Console.WriteLine(lineOfCredit.GetAccountHistory());
    

    Or, you could also do it like this:

    var interestEarning = new InterestEarningAccount ("interest earning", lineOfCredit.Balance);
    Console.WriteLine(lineOfCredit.GetAccountHistory());
    
    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Collin Brittain 36 Reputation points
    2020-12-04T17:59:08.417+00:00

    What's stopping you from using both? Your commented out line in Program.cs is missing ; at the end of the line. Perhaps that's why it wouldn't compile with it uncommented.

    1 person found this answer helpful.
    0 comments No comments

  2. BenTam 1,581 Reputation points
    2020-12-05T04:10:47.177+00:00

    Hi Collin,

    Thanks for your reply. I post the program.cs for your comments below. Is the following new statement correct?

    • var interestEarning = new InterestEarningAccount("interest earning", 0);

    However, this new statement will cause its parent class "BankAccount" another time. And the account number will be reset! I'd be thankful if you can solve the problem.

    45389-program.gif

    0 comments No comments