Question 1
Objective: In this task you will be required to demonstrate your mastery / understanding of the C# programming language. In the first few weeks of the unit we reviewed the basic syntax for constructing an object-oriented application. As such, the instructions in the question below should allow you to develop a working application straightforwardly. To complete this task you will need to know how to develop logic for a program (knowledge from the pre-requisite unit) and the syntax of the C# programming language (from studies in this unit).
The task that you will be completing in this question is to prepare an application that models a system for bank accounts. This question will guide you through constructing the bulk of the application with support for a savings account, the next question will extend this application.
Upon completing all of the requirements for this question, your program should produce the following output: see image.
Along with this question, two C# program files to be used in completing the assignment:
- Program.cs - this file contains the Main method which creates the initial data and invokes the methods in the AccountDB class to produce of the basic report;
- AccountDB.cs - this file contains the AccountDB class which stores references to all the Account and Customer objects and coordinates the display of the report lines.
No modifications are permitted to these files for this question.
Start by creating a new C# console application containing the above two files. The following instructions tell you how to complete the application for this question:
Create a new class 'Customer' with the following features:
- A private string attribute named '_Name'.
- A public read-only property named 'Name' which encapsulates the above attribute.
- A private List< > of SavingsAccount objects named '_Accounts'.
- A public read-only property named 'Accounts' which encapsulates the above attribute and returns a ReadOnlyCollection< >.
- Hint: Refer to the provided AccountDB class for how to do this.
- A public custom constructor which accepts a single string parameter named 'name' that initializes the matching attribute/s above.
- A public method named 'AddAccount' which accepts a single SavingsAccount object parameter named account and returns void:
- This method first checks to make sure the specified account has not already been recorded for this customer (object reference is stored in the _Accounts collection). If the account has already been recorded, the method performs no further action.
- Adds the account to the the _Accounts collection.
- Invokes the SavingsAccount's RecordCustomer() method, passing the current object as a parameter, to establish a bidirectional association. Hint: You may not fully understand this step until you complete the SavingsAccount class, below.
- Override the ToString() method to return the customer's name.
Create a new class 'SavingsAccount' with the following features:
- A public decimal constant named 'DEFAULT_OPENING_BALANCE' which has a zero value.
- A public string property 'AccountType' which returns the value "Savings Account".
- A private decimal attribute named '_OpeningBalance';
- A public read-only property named 'OpeningBalance' which encapsulates the above attribute.
- A public read-only property named 'OpeningBalanceString' which returns the opening balance in currency format appended with " CR" (note that there is a space character appearing before the CR)
- A private List< > of Customer objects named '_Owners';
- A public read-only property named 'Owners' which encapsulates the above attribute and returns a ReadOnlyCollection< >. Hint: Refer to the provided AccountDB class for how to do this.
- A private List< > of ITransaction objects named '_Transactions'.
- A public read-only property named 'Transactions' which encapsulates the above attributes and returns a ReadOnlyCollection< > Hint: Refer to the provided AccountDB class for how to do this.
- A public read-only decimal property named 'Balance' which returns the current balance of the account (opening balance plus the value of any stored transactions).
- A public custom constructor which accepts a single decimal parameter named 'openingBalance' which initializes the matching attribute/s above.
- A public parameter-less constructor which invokes the custom constructor defined in the previous step using an initializer, providing the default balance defined in the constant, above.
- A public method named AddTransaction which accepts a single ITransaction parameter named 'transaction' and returns a boolean value.
- The method checks that the transaction is not already recorded on the account, returning false if the transaction is already recorded.
- The method checks that the account balance will not become negative if the transaction were to be recorded, returning false if the transaction would result in a negative balance.
- Otherwise, the method adds the transaction to the _Transactions list and returns true.
- A public method named RecordCustomer which accepts a single Customer parameter named 'customer' and returns void.
- The method checks that the customer object's Accounts (List) property does contain the account and that the _Owners list does not contain the customer. If these two conditions are satisfied, the method adds the customer to the _Owners list.
- Override the ToString() method to return current balance of the account in currency format appended with " CR" (note that there is a space character appearing before the CR).
Create a new public interface 'ITransaction' with the following features:
- A read-only string property 'Description'.
- A read-only decimal property 'Amount'.
- A read-only decimal property 'Value'.
Create a new abstract class 'DecreaseTransaction' with the following features:
- Implements the ITransaction interface.
- Create an appropriate instance variable to store the description and implement the associated property from the interface.
- Create an appropriate instance variable to store the amount and implement the associated property from the interface.
- Implement the Value property by returning the negative of the amount.
- A protected custom constructor with a string parameter 'description' and decimal parameter amount and initialize the above instance variables.
- Override the ToString() method to return the Amount in currency format.
Create a new abstract class 'IncreaseTransaction' with the following features:
- Implements the ITransaction interface.
- Create an appropriate instance variable to store the description and implement the associated property from the interface.
- Create an appropriate instance variable to store the amount and implement the associated property from the interface.
- Implement the Value property by returning the amount.
- A protected custom constructor with a string parameter 'description' and decimal parameter amount and initialize the above instance variables.
- Override the ToString() method to return the Amount in currency format.
Create a new class 'Deposit' with the following features:
- Inherits from the IncreaseTransaction class.
- A custom constructor with decimal parameter 'amount' which invokes the base constructor providing the literal "Deposit" for the description and passing the amount parameter through.
- Override the ToString() method to return the base class' ToString result appended with " CR" (note that there is a space character appearing before the CR).
Create a new class 'Withdrawal' with the following features:
- Inherits from the DecreaseTransaction class.
- A custom constructor with decimal parameter 'amount' which invokes the base constructor providing the literal "Withdrawal" for the description and passing the amount parameter through.
- Override the ToString() method to return the base class' ToString result appended with " DR" (note that there is a space character appearing before the DR).
Build, test, and debug your program. Once complete, keep a copy to submit as your Question 1 solution (Question 1 is marked separately to Question 2).
Question 2
Objective: In this task you will be required to demonstrate your mastery / understanding of object-oriented relationships by extending your solution to the first task. This task focuses on Weeks 4-6 (Relationships, Inheritance, and Polymorphism). Unlike the first task, you are not provided with step-by-step instructions to complete this task. To complete this task you will need to know how to create objects, establish relationships between them, and work with those objects/relationships to build effective functionality, i.e., to demonstrate you can successfully write code using an object-oriented programming language.
For this task you are required to extend your solution to the first question to support customers having two different types of accounts: a savings account (already written in Question 1), and a credit card account (you are required to write this). The following specifications must be satisfied:
- Inheritance and polymorphism must be exploited where appropriate;
- Credit cards have a credit limit imposed on them, which is $2000 by default;
- Credit cards do not have deposits or withdrawals, they have payments (CR) and purchases (DR).
- Credit card balances increase when purchases are made and decrease when payments are made;
- Credit card balances can either represent money owed (a 'DR' balance), where the customer has not paid for all their purchases, or money held by the bank on behalf of the customer (a CR balance), where the customer has paid more money than the value of their purchases, there is no such thing as a negative balance - the account is either in debit (DR) or credit (CR);
- You must update the Program class' method 'LoadDefaultData to appropriately demonstrate the correct functioning of your extension. The AccountDB class will need to be modified to allow credit card accounts to be recorded. No other changes to the Program class or AccountDB class are permitted for this question; and
- The output for your program must be similar to the output shown above for Question 1, subject to the changes required for this question.
Build, test, and debug your program. Once complete, submit your solution to this question separately to your Question 1 solution (Question 1 is marked separately to Question 2).