Course Book Intro To Programming 2 ATU Sligo Ireland

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 71

1

Introduction to Programming 2

Vivion Kinsella

2
Sources I have used when writing up these notes
1. Murach’s c# 2012
2. https://www.thecodingguys.net/tutorials/csharp/csharp-tutorial/
3. https://www.geeksforgeeks.org/c-sharp-namespaces/
4. https://www.tutorialspoint.com/csharp/
5. https://docs.microsoft.com/en-us/dotnet
6. https://rubygarage.org/blog/most-basic-git-commands-with-examples

Book Recommendations
1. All the above +
2. Visual C# 2017, An Introduction to Object-oriented Programming, Joyce Farrell

Tools – similar to semester 1


1. https://visualstudio.microsoft.com/vs/community/
2. A really super learning website you should sign up to:
a. Codewars – here you will be presented with a number of coding challenges
(at different levels of difficulty – start at Kata 8) and gain honour as you
progress. It is really only now that you have a handle on the fundamental
that you can really enjoy this.
3. JDoodle
4. Git/GitHub

Thanks to Therese Hume for proof reading and additions


Cover : The Submariner (detail) 2020 by Elizabeth Kinsella Acrylic on Canvas

3
Contents

Chapter 1 :Introduction 4
Chapter 2 : Quick review 5

Data
Selection
Loops
Methods
Arrays

Chapter 3 : String handling 19


Chapter 4 : Data Validation 25
Chapter 5 : Exception Handling 30
Chapter 6 : File Handling 36
Chapter 7 : Object Oriented Programming 41
Chapter 8 : Miscellaneous 62
Chapter 9: Software Design Fundamentals 65
Appendix 1 : Question Sheets 69

4
Chapter 1 : Introduction
What is this module going to cover?
This module shall build on the fundamentals of programming covered in semester 1. Initially
we will revisit some of the material from semester 1 and re-enforce our knowledge and
understanding.
Then we will learn how to develop solutions to problems that make use of string handling,
data validation, exception handling, file handling and object oriented techniques.
I’m really looking forward to it, I hope you are too!

5
Chapter 2 – A Quick Review

Data in programs

• Programs are made up of data and operations that work on that data
• C# programs contain variables that hold the data to be processed
• The program must declare each variable before it is used
• Variables are of a particular data type
• The type of a variable determines what a program can store in it
• The C# language is strongly typed in that the compiler will prevent you from combining
data types ways it things are wrong
• This is to make programs more reliable

Declaring a variable with the keyword var

C# is a strongly typed language which means, you must declare a variable type before you
can use it. But what if you don’t know the type of the variable? C# lets you declare local
variables without giving them explicit types. It is possible with the help of the var type
variable.

6
The var keyword is used to declare a var type variable. The var type variable can be
used to store a simple data type, a complex type, an anonymous type, or a user-defined
type. We have only used simple types so far.

// string value
var name = "Pat Ryan";
Console.WriteLine($"var holds a string = {name}");
// int value
var age = 25;
Console.WriteLine($"var holds an int = {age}");
// string value
var salary = 45000.65;
Console.WriteLine($"var holds a double = {salary}");

Restrictions on implicit type variables


The following restrictions apply to implicitly-typed variable declarations:
• var can only be used when a local variable is declared and initialized in the same
statement; the variable cannot be initialized to null, r to a method group, or an
anonymous function.

• var cannot be used on fields at class scope.

• Variables declared by using var cannot be used in the initialization expression.

• Multiple implicitly-typed variables cannot be initialized in the same statement.

When to use var


Use of var is not recommended everywhere. The var was created to handle declarations
when the type is not known, such as generic types, lambdas, and query expressions (we’
come across these next year). If you already know the type of a variable, you must declare
that explicitly. Remember, if you don’t declare a variable explicitly, the compiler must do
extra work to determine the type. While the cost of this operation may not be significant,
it’s just unnecessary burden on the compiler.
• Don’t use var for simple local variable types that are known to you.

• Here are some of the common uses of the var keyword.

o Use var when you’re not sure what type of data will be stored in a variable.
o Use in anonymous types and anonymous collections
o Its real value will become more apparent in year2.

7
Selection

As we saw last semester, the structure mostly used for selection is if/if.. else.

A second structure which can be useful sometimes is switch. Here we look again at the
switch statement – it was in book 1, but we didn’t spend any time on it.

8
Switch statement

• The switch statement provides another means to decide which statement to execute
next when there are more than 1 alternative.

• The switch statement evaluates an expression, then attempts to match the result to
one of several possible cases.

• Each case contains a value and a list of statements.

• The flow of control transfers to statement list associated with the first value that
matches.

• The expression of a switch statement must result in an integral data type, like an
integer or character or a string.

• Note that the implicit boolean condition in a switch statement is equality - it tries to
match the expression with a value

• A switch statement can have an optional default case as the last case in the
statement

• The default case has no associated value and simply uses the reserved word default

• If the default case is present, control will transfer to it if no other case value matches

• If there is no default case, and no other value matches the expression, control falls
through to the statement after the switch

• A break statement is used as the last statement in each case's statement list

• A break statement causes control to transfer to the end of the switch statement.

• We can group cases that have corresponding statements.

9
Figure 1 Switch Syntax

10
Example

class Program
{
static void Main(string[] args)
{

// read in a number between 1 and 7 representing days of the week


// output the correspoding day name
int dayNum;
string message;

Console.WriteLine("Enter day number : ");


dayNum = int.Parse(Console.ReadLine());

switch (dayNum)
{
case 1: // when dayNum has a value of 1 execute this case
message = "Monday";
break;
case 2:
message = "Tuesday";
break;
case 3:
message = "Wednesday";
break;
case 4:
message = "Thursday";
break;
case 5:
message = "Friday";
break;
case 6:
message = "Saturday";
break;
case 7:
message = "Sunday";
break;

default:
message = "error";
break;
}

Console.WriteLine(message);

11
Example : multiple cases that result in the same outputs

class Program
{
static void Main(string[] args)
{

// read in a number between 1 and 7 representing days of the week


// output a message indicating if a weekday or a weekend day
int dayNum;
string message;

Console.WriteLine("Enter day number : ");


dayNum = int.Parse(Console.ReadLine());

switch (dayNum)
{
case 1:
case 2:
case 3:
case 4:
case 5:
message = "Midweek day"; // when dayNum has a value of 1,2,3,4 or
5 execute this case

break;
case 6:
case 7:
message = "Weekend day";
break;

default:
message = "error";
break;
}

Console.WriteLine(message);

12
Loops
As we’ve already seen, there are three main structures used to enable repetition of
statements or blocks of statements. These work in slightly different ways.

13
Methods
As our programs have started to get bigger and the problems we are solving more complex,
the simple structure of putting all our code into the Main() method becomes very unwieldly
and doesn’t reflect our divide and conquer approach to problem solving. A better approach
is to use multiple methods where each method performs a specific task.

We can write two types of method:


1. A non – return type (void) method that performs some process, but does not return any
value to the calling method.
2. A return type method that returns the result of some process to the calling method.

Sharing data between methods


We can share data by either:
1. Declaring variable at class level making their scope class wide, that is all methods in
the class can use the variable

2. If the data is declared locally, i.e. inside a method we can share it by passing the
variable to the called method through its parameter list.

14
When passing values, we can either
1. Pass by value : we give a copy of our data to the called method, meaning the called
method has only read access to our data, it cannot modify it. This is the default
mechanism as it is the most secure.

2. Pass by reference : we give the address of our data to the called method, giving it
read/write access to our data-always ask are you happy to do this? We specify this
type of passing by placing Ref or Out in from of the parameters. Use Ref when
parameter has an initial value, Out when parameter has no initial value.

Example : Pass a bank balance to a method, update the balance if sufficient funds available,
return true if transaction successful otherwise return false.

static void Main(string[] args)


{
int myBalance = 100;
int myWithdrawal = 35;
bool result = WithrawCash(ref myBalance, myWithdrawal); // must pass by
ref to allow myBalance be changed
if (result == true)
{
Console.WriteLine($"Take cash - new balance = {myBalance}");
}
else
{
Console.WriteLine("Sorry - Insufficent funds");
}
}

// upddate balance and return true if withdrawal ok ..otherwise return false


static bool WithrawCash(ref int balance, int cashAmount)
{
bool flag;
if (balance >= cashAmount)
{
balance = balance - cashAmount;
flag = true;
}
else
{
flag = false;
}
return flag;
}

15
Arrays
An array stores a fixed-size sequential collection of elements of the same type. An array is used to
store a collection of data, it is often more useful to think of an array as a collection of variables of
the same type stored at contiguous memory locations.

• We know how to create a variable:


int sales1;

• This will create a variable which can hold a single integer value

• The variable has the identifier sales

• If we want to store more data, one approach is to create more variables:


int sales1;
int sales2;
int sales3;
int sales4

• But if we have a lot of sales, image 4000, this could get very tedious and make
coding to manage these very difficult

• An array lets us create a row of variables which we can index using a subscript

• Declaring and initialising an array


int [] sales = new int [4];

• sales is a reference to an array of integers which contains 4 elements

• Once you have your array you can place values into the elements in it:
int [] sales = new int [4];
sales [0] = 5;
sales [1] = 7
sales [2] = 8
sales [3] = 10;
5 7 8 10
[0] [1] [2] [3]

• The value in the square brackets is called a subscript /index

• Console.Writeline(“Sales 1 = {0}”, sales[0]”)

16
Prints
Sales 1 = 5

• Note that the initial element has a subscript of 0

• Note the last element has a subscript of 3 (length of array – 1)

• Watch out! - It’s common to introduce off-by-one errors when using arrays

• If you try to access an element which is not in the array (perhaps by using a subscript
which is too large or less than zero) your program will fail

• For example, if the array sales can hold 4 values, it can only be indexed using the
numbers 0 to 3

Subscripts

• Subscripts become very powerful when we discover that we can use a variable as a
subscript:
static void Main(string[] args)
{

int[] sales = new int[4];


// fill array with values from keyboard
for (int i = 0; i < 4; i = i + 1)
{
Console.Write("Enter sales amount {0}: ", i + 1); // i starts at 0
sales[i] = int.Parse(Console.ReadLine());

}
}

• This will read in and store 4 sales values

• Subscripts start at 0, end at 3

• Each array has a public property called Length that stores the size of the array
- once an array is created, it has a fixed size
- It is referenced using the array name:
sales.Length

• Note that Length holds the number of elements, not the largest index

17
• This can be very handy when we want to write a method that will work with an array
of any length
// return the sum of all values stored in an array
// note how array is declared in parameter list
// note that by default arrays are passed by reference
// why do you think this is so?
static int AddUp(int[] myArray)
{
int sum = 0;
for (int i = 0; i < myArray[i]; i++)
{
sum = sum + myArray[i];
}
return sum;
}

Initialising Arrays

• An initialiser list can be used to instantiate and initialize an array in one step

• The values are delimited by braces and separated by commas.


o The list enables allocation of space for the array – the number of elements in
the initialiser list determines the size (length) of the array
o Elements in array are initialized with the values in the initialiser list
Examples:
int[] units = {147, 323, 89, 933, 540};
char[] letterGrades = {'A', 'B', 'C', 'D', 'F'};
string[] wordList = {“cs101“, “computer", “television"};

18
Two – Dimensional Arrays

• You can add an extra dimension by creating another subscript:


int [,] board = new int [3,3];
board [1,1] = 34; // board(row,column)
board [0,2] = 56;
board [2,0] = 78

• The subscripts are now row and column values

56
34
78

class Program
{
static void Main(string[] args)
{
// print contents of all elements in a 2d array
int[,] board = new int[3, 3];
board[1, 1] = 34; // board(row,column)
board[0, 2] = 56;
board[2, 0] = 78;

for (int row = 0; row < 3; row++)


{
for (int column = 0; column < 3; column++)
{
Console.Write(board[row,column] + " ");
}
Console.WriteLine();
}

Arrays have many built in methods, a few are:

• Copy (array1,array2,length);

• BinarySearch(arrayName,value);

• Sort(arrayName)

• Example: sort an array of values into ascending order


Array.Sort(myArray);

19
Chapter 3 - String Handling
The String class has numerous methods that help you in working with the string objects.
There are lots of times when writing a program we will want to manipulate strings, for
instance.

• Comparing two strings


• Convert a string from uppercase to lower case
• Check the length of a string, say a password
• Check that a particular part of a string contains a particular value – for example is the
first character in a password alphabetic
• Become a spy and do some encryption/decryption of secret messages (exciting!)
• Can you think of some examples?
The following table provides some of the most commonly used methods −

No. Methods & Description

1 public static int Compare(string strA, string strB)

Compares two specified string objects and returns an integer that indicates their relative
position in the sort order.

2 public static int Compare(string strA, string strB, bool ignoreCase )

Compares two specified string objects and returns an integer that indicates their relative
position in the sort order. However, it ignores case if the Boolean parameter is true.

3 public static string Concat(string str0, string str1) // overloaded with 3 others

Concatenates two string objects. The other deal with 3 and 4 bjects

6 public bool Contains(string value)

Returns a value indicating whether the specified String object occurs within this string.

7 public static string Copy(string str)

Creates a new String object with the same value as the specified string.

8 public void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count)

Copies a specified number of characters from a specified position of the String object to a
specified position in an array of Unicode characters.

20
9 public bool EndsWith(string value)

Determines whether the end of the string object matches the specified string.

10 public bool Equals(string value)

Determines whether the current String object and the specified String object have the same
value.

11 public static bool Equals(string a, string b)

Determines whether two specified String objects have the same value.

12 public static string Format(string format, Object arg0)

Replaces one or more format items in a specified string with the string representation of a
specified object.

13 public int IndexOf(char value)

Returns the zero-based index of the first occurrence of the specified Unicode character in the
current string.

14 public int IndexOf(string value)

Returns the zero-based index of the first occurrence of the specified string in this instance.

15 public int IndexOf(char value, int startIndex)

Returns the zero-based index of the first occurrence of the specified Unicode character in this
string, starting search at the specified character position.

16 public int IndexOf(string value, int startIndex)

Returns the zero-based index of the first occurrence of the specified string in this instance,
starting search at the specified character position.

17 public int IndexOfAny(char[] anyOf)

Returns the zero-based index of the first occurrence in this instance of any character in a
specified array of Unicode characters.

18 public int IndexOfAny(char[] anyOf, int startIndex)

Returns the zero-based index of the first occurrence in this instance of any character in a
specified array of Unicode characters, starting search at the specified character position.

21
19 public string Insert(int startIndex, string value)

Returns a new string in which a specified string is inserted at a specified index position in the
current string object.

20 public static string PadRight(int value) // also one for PadLeft

Return a string that’s right aligned and padded on the left with spaces so it is the specified
length

21 public static string Join(string separator, params string[] value)

Concatenates all the elements of a string array, using the specified separator between each
element.

22 public static string Join(string separator, string[] value, int startIndex, int count)

Concatenates the specified elements of a string array, using the specified separator between
each element.

23 public int LastIndexOf(char value [,start index])

Returns the zero-based index position of the last occurrence of the specified Unicode character
within the current string object.

24 public int LastIndexOf(string value [,start index])

Returns the zero-based index position of the last occurrence of a specified string within the
current string object.

25 public string Remove(int startIndex)

Removes all the characters in the current instance, beginning at a specified position and
continuing through the last position, and returns the string.

26 public string Remove(int startIndex, int count)

Removes the specified number of characters in the current string beginning at a specified
position and returns the string.

27 public string Replace(char oldChar, char newChar)

Replaces all occurrences of a specified Unicode character in the current string object with the
specified Unicode character and returns the new string.

28 public string Replace(string oldValue, string newValue)

22
Replaces all occurrences of a specified string in the current string object with the specified
string and returns the new string.

29 public string[] Split(params char[] separator)

Returns a string array that contains the substrings in the current string object, delimited by
elements of a specified Unicode character array.

30 public string[] Split(char[] separator, int count)

Returns a string array that contains the substrings in the current string object, delimited by
elements of a specified Unicode character array. The int parameter specifies the maximum
number of substrings to return.

Substring(StartIndex[,length])

Return a string that starts at the specified position and has the specified length

31 public bool StartsWith(string value)

Determines whether the beginning of this string instance matches the specified string.

32 public char[] ToCharArray()

Returns a Unicode character array with all the characters in the current string object.

33 public char[] ToCharArray(int startIndex, int length)

Returns a Unicode character array with all the characters in the current string object, starting
from the specified index and up to the specified length.

34 public string ToLower()

Returns a copy of this string converted to lowercase.

35 public string ToUpper()

Returns a copy of this string converted to uppercase.

36 public string Trim() : remove all leading and trailing white space characters from current strin

23
// Demo of some string functions
class Program
{
static void Main(string[] args)
{
string address = "pat ryan,sligo";
// write out the first character

Console.WriteLine($"Test String = {address}");


Console.WriteLine($"The first character is : {address[0]}"); // 0 is the
index of first character

// write out the last character - note the use of Length – 1


// here we make use of the Length property to get the number of chars
Console.WriteLine($"The last character is {address[address.Length - 1]}");

// write out the individual characters that make up a string


for (int i = 0; i < address.Length; i++)
{
Console.WriteLine($"Character {i} = {address[i]}");
}

// check if string starts with "pat"


bool checkStart = address.StartsWith("pat");
Console.WriteLine($"Does the string start with \"pat\" ? -
{checkStart}");

// append the string "Ireland" to the end of the string


address = address.Insert(address.Length, ",Ireland");

Console.WriteLine($"New string with \"Ireland\" appended to the end -


{address}", );

// write a full name as initials


string fullName = "John Pat Ryan";

string firstInitial = fullName.Substring(0, 1);

int spacePos = fullName.IndexOf(" ");

string secondInitial = fullName.Substring(spacePos + 1, 1);

int secondSpace = fullName.IndexOf(" ", spacePos + 1);

string thirdInitial = fullName.Substring(secondSpace + 1, 1);

string newName = firstInitial + "." + secondInitial + "." + thirdInitial;

Console.WriteLine($"Initials of \"John Pat Ryan\" = {newName}");

24
// remove ' ', '$', '," and '*' from a string
// this has a 2 bugs... fix it

string funnyMessage = "Brexit is $ a great idea,*";


int l = funnyMessage.Length - 1;
for (int i = 0; i < funnyMessage.Length - 1; i++)
{
Console.WriteLine(funnyMessage[i]);
if (funnyMessage[i] == ' ' || funnyMessage[i] == '$' ||
funnyMessage[i] == ',' || funnyMessage[i] == '*')
{

funnyMessage = funnyMessage.Remove(i, 1);

}
}

Console.WriteLine($"\"Brexit is $ a great idea, *\" with non alphabetic


chars removed = {funnyMessage}"); }
}

Figure : Output from program

Did you fix the problem – it’s a bit tricky?

25
Chapter 4 - Data Validation – Checking for error conditions

Ok, let’s admit it, a lot of the programs that we have written up to now are brittle, that is
they will crash fairly easily or produce unexpected results. This can happen when we ask
the user

1. To enter a number and they enter a string or a blank instead.


2. To enter an integer but they enter a decimal instead
3. To enter a number within a particular range and they enter a number outside this
range

Can you think of other situations where your program has crashed?

Look what happened when we run this code and the user enters a string (I bet you’ve this
this quite a bit)

static void Main(string[] args)


{
int myAge;

Console.Write("Please enter your age : ");


myAge = int.Parse(Console.ReadLine());
}

Figure : Crashing – expecting a number but getting a string

26
Dealing with wrong data types

To avoid these situations we need to check that a user has entered data in the correct
format before we proceed to process this data further. This is going to take a little more
effort but we will end up with a more robust program and happier user

TryParse

The TryParse method converts the string representation of a number to its 32-bit signed
integer equivalent (or other numeric format). A return value indicates whether the
conversion succeeded.

Syntax

public static bool TryParse (string s, out int result);

Parameters

s : A string containing a number to convert the thing we are checking.

result : Integer value equivalent of the number contained in s, if the conversion succeeded,
or zero if the conversion failed. The conversion fails if the s parameter is null or Empty or is
not of the correct format. This parameter is passed uninitialized; any value originally
supplied in result will be overwritten.

TryParse returns true if s was converted successfully; otherwise, false. Note that an
overloaded version of TryParse allows us to check against min and max values.

27
Example : check that an integer value is entered
static void Main(string[] args)
{
string userInput;
int myAge;

Console.Write("Please enter your age : ");


userInput = Console.ReadLine(); // take in a string
// check that it is an integer
// if it is result will be true and number will be in myAge
// if false result will be false number will have a value of 0
bool result = int.TryParse(userInput, out myAge);
if (result == true)
{
Console.WriteLine("thank you for that");
// we can carry on our work safely now from here
}
else
{
Console.WriteLine("concentrate! - i asked for a number");
}

Example : Here is a slightly more elaborate example where we read through an array of
values and check each value to see if it is an integer.

static void Main(string[] args)


{
String[] values = { null, "160519", "9432.0", "16,667",
" -322 ", "+4302", "(100);", "01FA" };
for (int i = 0; i < values.Length; i++)
{
int number;
bool success = Int32.TryParse(values[i], out number);
if (success) // shorthand for (success == true)
{
Console.WriteLine($"Converted '{values[i]}' to {number}.");
}
else
{
Console.WriteLine($"Attempted conversion of '{values[i]}'
failed.");
}
}
}

// The example displays the following output:


// Attempted conversion of '<null>' failed.
// Converted '160519' to 160519.
// Attempted conversion of '9432.0' failed.
// Attempted conversion of '16,667' failed.
// Converted ' -322 ' to -322.
// Converted '+4302' to 4302.
// Attempted conversion of '(100);' failed.
// Attempted conversion of '01FA' failed.

28
More Data Validation – to cover a number of possible errors

Below is a really nice program that demonstrates the use of generic methods to do data
validation. These are methods that we could reuse in any program we write from now on.
We could just copy and paste the code into new projects but a better way would be to
include these in a static class, compile this and reference this class in any project where we
need to use them.

Here we want to allow a user to repeatedly enter their age until a valid value is entered.

The value entered must

• Must be an integer value


• Must be present
• Must be within the range 18 and 21

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

namespace ValidationDemo
{
class Program
{
static void Main(string[] args)
{
string inputString;
int age;
// keep asking user for there age until we are happy with value entered
do
{
Console.Write("Enter your age : ");
inputString = Console.ReadLine();
}
while (IsValidData(inputString,"age") == false);
// from here we can proceed with normal processing
}

static bool IsValidData(string inputString, string itemName)


{
if ((IsPresent(inputString, itemName) == true) && (IsInteger(inputString,
itemName) == true) && (IsWithinRange(inputString, itemName, 18, 21)))
{
return true;
}
return false;
}

29
static bool IsPresent(string textIn, string name)
{
if (textIn == "")
{
Console.WriteLine(name + " is a required field.", "Entry Error");
return false;
}
return true;
}
static bool IsInteger(string textIn, string name)
{
int num;

if (int.TryParse(textIn, out num) == true) // all went ok


return true;
else // there was a problem
Console.WriteLine(name + " must be an integer value.", "Entry
Error");

return false;
}

static bool IsWithinRange(string textIn, string name, int min, int max)
{
int number = int.Parse(textIn);
if (number < min || number > max)
{
Console.WriteLine(name + " must be between " + min + " and " + max
+ ".", "Entry Error");

return false;
}
return true;
}

}
}

Notice the way these methods can be injected with different values, allowing them to be
used in many different situations, for example the IsWithInRange() method could be
injected with a different prompt, a different name and different min and max values.

30
Chapter 5 – Exception handling

Overview

Exceptions are unusual runtime errors that can make a program behave abruptly if not
handled in the right way. Hence, most programming languages add exception handling
capabilities to allow us deal with these and potentially recover from them –error recovery.

As we have seen in the previous section we can anticipate some errors and can have code
checks that check if the data is ok before we do any processing on it.

But sometimes we have no control over circumstances that might affect our program.

For example, if our program tries to reference an array index that does not exist or tries to
read a file that does not exist, it may abort.

Example of a runtime error

static void Main(string[] args)


{

String[] locations = { "cork", "mayo", "kerry" };

for (int i = 0; i <= locations.Length; i++)


{
Console.WriteLine($"Fire at {locations[i]}");
}

C# provides exception handling facility to allow the programmer insert code to handle such
unexpected errors and allow the program to recover and continue executing, or to
terminate gracefully, whichever is appropriate.

31
Exception Classes in C#
C# exceptions are represented by classes. The exception classes in C# are mainly directly or
indirectly derived from the System.Exception class.

The following list provides some of the predefined exception classes derived from the
Sytem.Exception class −
• IndexOutOfRangeException
• OutOfMemoryException
• FormatException
• IOException
• FileNotFoundException
• Exception // unspecified

Exceptions have the following properties:

1. When your application encounters an exceptional circumstance, such as an index out


of range or a file not found, an exception is thrown

2. We use a try block around the statements that might throw exceptions.

3. Once an exception occurs within the try block, the flow of control immediately
jumps to an associated exception handler, if one is present.

4. An exception handler is a block of code that is executed when an exception occurs.


In C#, the catch keyword is used to define an exception handler.

5. If no exception handler for a given exception is present, the program stops executing
with an error message.

6. If a catch block defines an exception variable, you can use it to get more information
on the type of exception that occurred.

7. Exceptions can be explicitly generated by a program using the throw keyword.

8. Exception objects contain detailed information about the error, including the state of
the call stack and a text description of the error.

9. When an exception occurs, execution stops and control is given to the appropriate
exception handler. This often means that lines of code you expect to be executed are
bypassed. Some resource cleanup, such as closing a file (or landing all planes!),
needs to be done even if an exception is thrown. To do this, you can use a finally
block. A finally block always executes, regardless of whether an exception is thrown.

10. You can write your own custom exception classes

32
Syntax
try
{
// statements causing exception
}

catch( ExceptionName e1 )
{
// error handling code

} catch( ExceptionName e2 )

{
// error handling code
}

catch( ExceptionName eN )
{
// error handling code
}

finally
{
// statements to be executed
}

33
Example 1 – Try Catch
static void Main(string[] args)
{
int num1, num2;
double quotient;
bool isValid;

do // i ve put a loop in here so that user can correct their mistake


{
try
{
isValid = true;

Console.WriteLine("Enter the first number : ");


num1 = int.Parse(Console.ReadLine());

Console.WriteLine("Enter the second number : ");


num2 = int.Parse(Console.ReadLine());

quotient = Divide(num1, num2);


Console.WriteLine($"The quotient is {quotient}");
}
catch (ArithmeticException myError)
{

Console.WriteLine(myError.Message); // could put a more app


specific message if we wished
isValid = false;
}
catch (FormatException myError)
{
Console.WriteLine(myError.Message);
isValid = false;
}
catch (Exception myError) // unspecified exception
{
Console.WriteLine(myError.Message);
isValid = false;
}
finally // executed in all cases
{
Console.WriteLine("In Finally block");
}

}
while (isValid == false); // if there is a problem, try block is re
executed
}

public static double Divide(int numerator, int denominator)


{
if (denominator == 0)
throw new ArithmeticException("Cannot divide by zero"); // programmer
throwing an exception
else
return (double)numerator / denominator;
}

34
Example 2 Try - Catch
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace TryCatch
{
class Program // demo of try catch exception handling
{
static void Main(string[] args)
{
int code;

string[] msgArray = {"x","y","z"}; // initialize an array

string messageOut;

try
{

Console.Write("Enter code : ");


code = Convert.ToInt32(Console.ReadLine());

messageOut = msgArray[code];
} // end try

catch (IndexOutOfRangeException e)
{
Console.WriteLine("invalid code length");
Console.WriteLine(e.Message);

}
catch (FormatException e)
{
Console.WriteLine("code NOT numeric");
}

catch (Exception e) // catch any un specified exception


{
Console.WriteLine(e.Message);
}
finally // will always be executed - do clean up here
{
Console.WriteLine("PROGRAM TERMINATING");

}
}
}

35
Exception Handling – When to use – Best Practice

When should we use exception handling as opposed to coded checks?

The method to choose depends on how often you expect the event to occur.

• Use exception handling if the event doesn't occur very often, that is, if the event is
truly exceptional and indicates an error (such as index out of range). When you use
exception handling, less code is executed in normal conditions.

• Check for error conditions in code if the event happens routinely and could be
considered part of normal execution. When you check for common error conditions,
less code is executed because you avoid exceptions.

Example - Handle common conditions without throwing exceptions

For conditions that are likely to occur but might trigger an exception, consider handling
them in a way that will avoid the exception. For example, if you try to divide a number by
zero, you'll get a DivisionByZeroException. You can avoid this by using an if
statement to check the divisor before trying to do division.

// two approaches

if (b != 0) // using code to check all ok before we do operation, no need


for ex handler
{
ans = a / b;
}

// alternative
try // using exception handler to deal with problem if it occurs
{
ans = a / b;
}
catch (DivideByZeroException ex)
{
Console.WriteLine(ex.GetType().FullName);
Console.WriteLine(ex.Message);
}

36
Chapter 6 File Handling
Up to now all data that our programs have been working with has come directly from the
console or we have printed it to the console. When the execution of the program is finished
all data is lost. This is not always what we want, we may wish to have a record of the results
of our program or wish our program to take its data from a source other than the user.
Most applications will have this requirement. Just think of every time you go to an ATM,
you will enter some data directly, for example your PIN, but all your details like your bank
balance will be retrieved from some storage device that the bank is using, also when your
transaction is completed the ATM will want to have a record of the transactions and to
update your account, e.g. amend your balance.

We have a number of options as to how we might want to store this data, each has its own
merits and disadvantages. For example:

1. A relational data base (SQL Server, MS ACCESS)


2. A non-relational database (mongoDB)
3. A spreadsheet
4. A simple text file
5. A binary file

Over the coming years we will explore many of this techniques, but this year we will
concentrate on working with files:

• A file consists of data stored on disk.


• Maybe text files or binary files
• Text file contain text and can be edited and viewed in a text editor such as NotePad.
• Binary files contains unformatted binary data(e.g. .exe file, .mp3 file)
• Files may be created externally or be created directly from a c# Program
• To handle IO operations on files we use dedicated inbuilt file handling classes
o The FileStream class provides a Stream for a file, supporting read and write
operations.
o The StreamReader class provides methods file for reading from a steam
o The StreamWriter class provides methods for writing to a stream

To use these you must place :

Using System.IO at the top of your program

37
File handling : Example1

Let’s write a program to read the first line of text in a file stored on the debug folder of a
project called messages. This file will have been created using a simple text editor like
NotePad.
Steps
1. Create a FileStream object that connects to the file
2. Create a StreamReader object to allow us read from the
stream
3. Read first record
4. Display record
5. Close the stream

static void Read_Single_Line_Demo()


{
string lineIn; // we will use this to hold a line of data that we read
from the file

// open connection
FileStream fs = new FileStream("products.txt", FileMode.Open,
FileAccess.Read);

// create a StreamReader objects to allow us read from file


StreamReader inputStream = new StreamReader(fs);

lineIn = inputStream.ReadLine(); // read first line in file

Console.WriteLine(lineIn); // write first line in file to screen

inputStream.Close();

38
File handling : Example 2:

Let’s write a program to read in all the lines of text in a file stored in the debug folder called
messages
The ReadLine() method returns null when the end of file is reached. This will act as a
sentinel value to tell us to stop reading

Steps

1. Create a FileStream object that connects to the file


2. Create a StreamReader object to allow us read from the
stream
3. Read first record
4. Repeat until end-of-file
a. Process record
b. Get next Record
5. End Loop
6. Close stream

static void StreamReader_Demo_TextFile()


{
FileStream fs = new FileStream("messages.txt", FileMode.Open,
FileAccess.Read);

StreamReader inputStream = new StreamReader(fs);

string lineIn;

lineIn = inputStream.ReadLine(); // read first line in file

while (lineIn != null) // null signals end-of-file


{

Console.WriteLine(lineIn); // print line to console

lineIn = inputStream.ReadLine(); // read next line in file


}

inputStream.Close();

39
Working with Comma Separated Value (CSV) files

A Comma Separated Values (CSV) file is a plain text file that contains a list of data. These
files are often used for exchanging data between different applications
These files may sometimes be called Character Separated Values or Comma Delimited files.
They mostly use the comma character to separate (or delimit) data, but sometimes use
other characters, like semicolons. The idea is that you can export complex data from one
application to a CSV file, and then import the data in that CSV file into another application.
For example an excel spreadsheet can be saved as a CSV file.

The Structure of a CSV File


A CSV file has a fairly simple structure. For example, let’s say you have a few employees ,
and you want to store their name, email, address and salary. You’d create a CSV a file
containing text like this:

Bob Smith,bob@example.com,1 Main Street,34000


Mike Jones,mike@example.com,321 Sligo Avenue,50000

That’s all a CSV file really is. Some CSV files may have a headers at the top describing the
fields, they can contain thousands of lines and lots of entries on each line

Each line is often referred to as a record and the parts of each line the fields
It’s this simplicity of CSV files that allows us use them to easily export data and import it into
other programs.

40
// Program to read in all employees from the CSV file employee.txt
// print each employees details to a report
// calculate the total of all salaries paid
// calculate the average salary
// print total and average salary

static void CSV_Demo()


{
string lineIn;
string[] fields = new string[4];
int totalSalaries = 0;
int count = 0;

// open connection

FileStream fs = new FileStream("employees.txt", FileMode.Open,

FileAccess.Read);

StreamReader inputStream = new StreamReader(fs);

// print heading

Console.WriteLine("Employee Report");

Console.WriteLine($"{"Name",-10}{"Email",-10}{"Address",-
10}{"Salary",-10}");

lineIn = inputStream.ReadLine(); // get first record

// report body

while (lineIn != null) // keep going until we get to the end


signalled by a null

{
fields = lineIn.Split(','); // split input where ',' is

int salary = int.Parse(fields[3]);

totalSalaries = totalSalaries + salary;

count++;

Console.WriteLine($"{fields[0],-10}{fields[1],-10}{fields[2],-
10}{fields[3],-10}");

lineIn = inputStream.ReadLine(); // get the next record

int avgSalary = totalSalaries / count;

// report footing

Console.WriteLine($"Total = {totalSalaries}");
Console.WriteLine($"Average = {avgSalary}");
inputStream.Close();
}

41
42
Chapter 7- Object-Oriented Programming (OOP)
Object-Oriented Programming (OOP) is the term used to describe a programming approach
based on Objects and classes.
The object-oriented paradigm (fancy word for model) allows us to organise software as a
collection of objects that consist of both data and behaviour (methods).
In many ways it is modelling how things (objects) like humans, vehicles, animals, etc. act in
the real world.
For example you are an object of type human, you have data (your name, address, height,
skin colour etc.) and you have behaviours, like walk, talk, sit, jump, etc.

• What kind of data and behaviours might a tank object have if you were programming
a game?
So all the related data and methods are packaged together – when you think about it this
makes a lot of sense.
This is in contrast to the functional programming practice that only loosely connects data
and behaviour.
The move towards oop started in the 1980s, with almost all languages developed since 1990
having object-oriented features. Some popular languages have been re developed with
object-oriented features, e.g. object oriented Cobol – my first programming language!.
It is widely accepted that object-oriented programming is the most important and powerful
way of creating software and from this point forward all your programs will be fully object –
oriented. (up to now, our programs are a bit of a hybrid, our code has been written in a
functional style but we have been making use of classes and objects which are part of c#, for
example we have used the StreamReader class when file handling)

The object-oriented programming approach encourages:

• Modelling the real world


• Modularisation: where the application can be decomposed into modules – divide
and conquer
• Software re-use: where an application can be composed from existing and new
modules.
• An object-oriented programming language generally supports five main features:
o Classes
o Objects
o Inheritance
o Polymorphism
o Classification

43
Classes
You can think of a class as a template or blueprint of something. That something might be
A student
A car
A bank account
A bicycle
An employee
A weapon
In the case of say, an Employee, it will have certain features (attributes) that all Employees
have:
o Name
o Gender
o HourlyRate
o Employee Number

Employee data will also have certain tasks (behaviours) associated with it e.g.
o Calculate Pay
o Calculate Tax
o Calculate Bonus
______________

Thinking about a class to represent a car, can you think


What attributes it might have?
What behaviours might be associated with it?

44
Components of a class
We capture all of these attributes and functions in a class.

1. A class name – should be a meaningful noun (Employee) – start with a capital


2. Attributes/Fields, also called instance variables
3. Constructor(s) – Method(s) that create an instance of a class (an object)
4. Properties
a. Getters (or Accessors) – special methods that will return (get) the attributes
of a class
b. Setters (or Mutators) – special methods that will change the value of an
attribute in a class
5. The functions a class can perform - methods

How to write a class


General Structure

[Access Modifier] class Name


{
Members (attributes, constructor(s) getters, setters and methods)

• Access modifier - public | private | protected

– public any program can use this class

– private – can only be used within this namespace

– protected – can be use within the current namespace or derived


subclasses

– <none> default – same as private- accessible only within the


namespace

Deciding in what modifier to use is very dependent of the requirement of the class – how
you want it to be used, though generally classes tend to be public, attributes private and
methods public.

45
Objects
An object is an instance of a class, you could think of it as a variable. For example

// open connection
FileStream fs = new FileStream("products.txt", FileMode.Open,
FileAccess.Read);

This is creating an object of the FileStream class, we could create as many of these as are
needed:
// open connection
FileStream fs2 = new FileStream("products.txt", FileMode.Open,
FileAccess.Read);

Example of a Class :

Let’s look at an example of a class, with a single attribute, _name , two constructors. It has
one method PrintName()

class Employee
{
private string _name; // the name field

//default constructor
public Employee()
{

//parameterised constructor
public Employee(string n)
{
_name = n;
}

//method
public void PrintName()
{
Console.WriteLine("$Name is {_name}");

46
Working with Objects
An employee of a company is an instance an Employee, it has a name of Mary

class Program
{
// program to test our class
static void Main(string[] args)
{
Employee myEmployee; // declares an object of type Employee
myEmployee = new Employee(); // create an object of type employee
myEmployee.Name = "Mary"; // set the name of this employee to “Mary”
myEmployee.PrintName(); // call to the PrintName method
}
}

47
What the heck is going on?
Employee myEmployee;

This declares an object of type Employee named myEmployee, it is currently referencing


nothing, we say it is pointing at null. Null is the default value of reference-type variables.
Ordinary value types, sometimes called primitive types like int and double cannot be
null, when they are declared they are allocated an amount of memory, for example with an
int, 32 bits are allocated

myEmployee

null

A class provides the instructions to C# as to what is to be made, and what it can do. The new
keyword causes C# to use the class information to actually make an instance. We have seen
this keyword new before. We use it to create arrays. This is because an array is actually
implemented as an object, and so we use new to create it.
The thing that new creates is an object, an instance of a class.

myEmployee = new Employee();

Employee
myEmployee

myEmployee._name = “Mary”;

myEmployee Employee
_name : Mary

48
Constructors
A constructor is a special kind of method that is automatically called when an object is
created, this occurs when the new keyword is used. They normally perform initialisation or
setup operations such as storing initial values in attribute fields.
They are called constructors because they help construct an object
They have no return type (no need to use void) and must have the same name as the class.
Normally you will have a default constructor, this has no parameters and at least one other
constructor with 1 or more parameters.
You could think of a constructor as the piece of code that gives birth to the object. The
default constructor gives birth to an object where we know nothing about its attributes yet.
(we may set them later on)
Employee myEmployee = new Employee();

Whereas with a parameterised constructor, we know some of the attributes values at the
time of birth,

Employee myEmployee2 = new Employee (“Pat”);

myEmployee2 Employee
_name : Pat

We can have any number of constructors with different parameter lists, we call this
overloading. The constructor that we use will be dynamically selected at run time based on
the parameter list we use.

49
Properties – Accessors and Mutators
These are special methods that are used to the return (get) attributes and also change (set)
attributes of an object.
They combine aspects of both attributes and methods. To the user of an object, a property
appears to be an attribute, accessing the property requires the same syntax as you would
use if using an attribute.

To the implementer of a class, a property has one or two code blocks, representing get
accessor and/or a set accessor.

• The code block for the get accessor is executed when the property is read.
• The code block for the set accessor is executed when the property is assigned a new
value.
• A property without a set accessor is considered read-only.
• A property without a get accessor is considered write-only.
• A property that has both accessors is read-write.
• Unlike attributes, properties are not classified as variables. Therefore, you cannot
pass a property in method calls.

Properties have many uses:


• They can validate data before allowing a change;
• They can transparently expose data on a class where that data is actually retrieved
from some other source, such as a file or database;
• They can take an action when data is changed, such as raising an event, or changing
the value of other fields.

Properties are declared in the class block by specifying the access level of the field, followed
by the type of the property, followed by the name of the property, and followed by a code
block that declares a get accessor and/or a set accessor. For example:

50
The Get accessor
class Employee
{
private string _name; // the name field
public string Name // the Name property
{
get
{
return this._name;
}
}
}

// code to use this

class Program
{
// program to test our propery
static void Main(string[] args)
{
Employee myEmployee; // declares an object of type Employee
myEmployee = new Employee(“Mary”); // create an object of type employee
with the name Mary
Console.WriteLine($"Name is {Name}"); // the get accessor is invoked
}
}

When executed this will print :


Name is Mary

51
Here is an example where the get accessor includes a code check to make sure the name is
not pointing at null, if it is it return the text “na”.

class Employee
{
private string name;
public string Name
{
get
{
if (name != null) // if set to something
return this.name;
else
return "NA";
}
}
}

// code to use this

class Program
{
// program to test our propery
static void Main(string[] args)
{
Employee myEmployee; // declares an object of type Employee
myEmployee = new Employee(); // create an object of type employee
Console.WriteLine($"Name is {Name}"); // the get accessor is invoked
}
}

When executed this will print :


Name is na

52
The Set accessor
The set accessor resembles a method whose return type is void. It uses an implicit
parameter called value whose type is the type of the property. In the following example, a
set accessor is added to the Name property.

class Employee
{
private string _name; // the name field
public string Name // the Name property
{
get
{
return this._name;
}
set
{
this._name = value;
}
}
}

class Program
{
// program to test our class
static void Main(string[] args)
{
Employee myEmployee; // declares an object of type Employee
myEmployee = new Employee(); // create an object of type employee
myEmployee.Name = "Mary"; // set the name of this employee to “Mary”
Console.WriteLine($"Name is {Name}"); // the get accessor is invoked
}
}

When executed this will print :


Name is Mary

53
Note that the set accessor could include code to check the value is appropriate before being
set

Example : Using the set accessor to check an employees name before setting, in this case
let’s assume we don’t want any employee with the name Frank (sorry Frank!)

class Employee
{
private string _name; // the name field
public string Name // the Name property
{
get
{
return this._name;
}
set
{
if (value != "Frank")
_name = value;
else
this._name = “na”;
}
}
}

class Program
{
// program to test our class
static void Main(string[] args)
{
Employee myEmployee; // declares an object of type Employee
myEmployee = new Employee(); // create an object of type employee
myEmployee.Name = "Frank"; // set the name of this employee to “Frank”
Console.WriteLine($"Name is {Name}"); // the get accessor is invoked
}
}

When executed this will print :


Name is na

54
Auto-implemented property

Auto-implemented properties make property-declaration more concise when no


additional logic is required in the property accessors. When you declare a
property as shown in the following example, the compiler creates a private,
anonymous backing field that can only be accessed through the property's get and
set accessors.

public double HourlyRate { get; set; }

Static Keyword in classes


If we use the static keyword when declaring a method or a variable then that method or
variable belongs exclusively to the class definition and will never be copied to an instance of
the class. When we leave the static keyword out, then every instance of the class will get its
own copy of the method or variable.
For example if we want to keeps track of the number of employees that have been created,
we will need a static variable to keep track

public static int lastEmployeeNumber;

So, if we added an employeeNumber attribute to our employee class, then in our


constructor code we might have

public Employee()
{
lastEmployeeNumber++;
employeeNumber = lastEmployeeNumber;
}

55
The Object class
In C#, every class is actually a sub class of a very important class, called the Object class. The
Object class has a number of methods that are made available to all other classes.

The ToString() method is one of these, it returns a string representation (description) of an


object.

It is good practice to write one of these methods for each of our own classes, and let ours
override (replace) the base method. Typically it will return a string with all/some of our
objects attributes.

For example, our employee class might include the following replacement ToString()
method.

public override string ToString()

Console.WriteLine(“the name of the Employee is {0}, Name);

Not the use of the word override, this tells our method to override the ToString()
method of the base class.

56
Example : Here is a complete example of a program that uses a class
Attributes : name, gender, hourly rate and employee number
Methods : CalcPay and ToString
/*

# Author VK

# This class represents a blueprint of an employee with four attributes and two
# methods
*
*/
class Employee

{
// attributes
private string _gender;
private string _name;
private int _employeeNumber;

// static variable belong to class, no individual object has this


public static int lastEmployeeNumber;

// Name property used to get and set the name attribute of an object
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}

// Gender property used to get and set the gender attribute of an object
public string Gender
{
get
{
return _gender;
}
set
{
_gender = value;
}
}

57
// HourlyRate property used to get and set the hourly rate attribute of an object
// here i am using an auto-implemented property
// auto-implemented properties make property-declaration more concise when no
// additionallogic is required in the property accessors. When you declare a
// property as shown in the following example, the compiler creates a private,
// anonymous backing field that can only be accessed through the property's get and
// set accessors.
public double HourlyRate { get; set; }

// EmployeeNumber property used to get and set the employee number attribute of an
object
public int EmployeeNumber
{
get
{
return this._employeeNumber;
}
set
{
_thhis._employeeNumber = value;
}

// Default construct
public Employee()
{
lastEmployeeNumber++; // increment the static variable by 1
EmployeeNumber = lastEmployeeNumber; // assign to the employee number
attribute
}

//parameterised constructor
public Employee(string n, string b, double p)
{
Name = n;
Gender = b;
HourlyRate = p;
lastEmployeeNumber++; // increment the static variable by 1
EmployeeNumber = lastEmployeeNumber; // assign to the employee number
attribute

}
// Method tp print the attributes of an object
public override string ToString()
{
return "Name: " + Name + " Gender : " + Gender + " Rate : " + HourlyRate +
" Employee # : " + EmployeeNumber;
}

// a=Method to calculate an employees pay, employees work 40 hours


public virtual double CalcPay()
{
return 40 * HourlyRate;

}
}

58
// program to make use of our Employee class
class Program
{
static void Main(string[] args)
{
// code to test our classes

Employee employee = new Employee(); // create an employee using the


default constructor
Console.WriteLine(employee.ToString()); // print this employees attributes
using the ToString()method of the employee object
Console.WriteLine($"Pay = { employee.CalcPay()}"); // call the CalcPay
meth of the employee

employee.Name = "John"; // set the attributes of the employee using


Setter
employee.Gender = "Male";
employee.HourlyRate = 10;

Console.WriteLine(employee.ToString()); // print this employees


attributes using the ToString()method of the employee object

Console.WriteLine($"Pay = {employee.CalcPay()}");

employee = new Employee("sarah", "female", 15); // create a new employee


using parameterised constructor
Console.WriteLine(employee.ToString());
Console.WriteLine($"Pay = {employee.CalcPay()}");

// create an array of employees


Employee[] Employees = new Employee[2];

Employees[0] = new Employee("Mary", "female", 50);


Employees[1] = new Employee("Ann","female", 25);

// print details of all employees


Console.WriteLine("\n Array of 2 employees \n");

for (int i = 0; i < 2; i++)


{
Console.WriteLine(Employees[i].ToString());
Console.WriteLine("Your pay = " + Employees[i].CalcPay());

}
}

59
Inheritance

With classes and objects we have seen that we can very neatly package the attributes and
functionality of real world objects.

This is great because it allows to manage complex solution (divide and conquer) plus we can
reuse our classes in loads of applications.

For example, if we were developing a new game we can reuse a previously written weapon
class or in a new payroll system we can reuse our Employee class.

There might be situations where we want to reuse a class, but slightly modify its attributes
and/or functionality. Oh-no, does this mean we can’t reuse our class? The great news is, yes,
we can make use of our existing class. Inheritance to the rescue!

When creating a class, instead of writing completely new attributes and functions, the
programmer can designate that the new class (the child or subclass or derived class) should
inherit the members of an existing class (the parent or superclass or base class).

Consider the case of our Employee class, if we were now to consider Part time employees,
all these will have the same characteristics as an Employee but in addition they will have a
number of hours worked attribute and a modified CalPay() method, where their pay is
calculated based on the number of hours they have worked. (rather than 40 for all
employees)
(We can view our Employee class as a generalisation – think what characteristics do all
employees have (regardless of being full or part time)?

60
Base and Derived Classes
A class can be derived from more than one class , which means that it can inherit data and
functions from multiple base classes or interfaces.

The syntax used in C# for creating derived classes is as follows –

<acess-specifier> class <base_class> {


...
}

class <derived_class> : <base_class> {


...
}

In our example the base class is the Employee and its derived class is the PartTimeEmployee
class

61
Initializing Base Class
The derived class inherits the base class member variables and member methods. Therefore
the super class object should be created before the subclass is created.

The following program demonstrates this −

class PartTimeEmployee : Employee // inherits from Employee class

{
private int _hoursWorked; // this is the new attribute for part time
employeess
public int HoursWorked {
get
{
return _hoursWorked;
}
set
{
_hoursWorked = value;
}
}

public PartTimeEmployee() :base()


{

public PartTimeEmployee(string n, string gender, double hourlyRate, int hrs)


: base (n, gender, hourlyRate)
{

_hoursWorked = hrs;
}

public override double CalcPay()


{
return HoursWorked * HourlyRate;

public override string ToString() // note that this over rides(replaces) all
super level toString methods
{

return base.ToString() + " HoursWorked : " + HoursWorked;


}
}

62
Program to test our use of inheritance

Employee[] AllEmployees = new Employee[4];

AllEmployees[0] = new PartTimeEmployee("john", "male", 20, 10);


AllEmployees[1] = new PartTimeEmployee("owen", "male", 20, 15);
AllEmployees[2] = new Employee("tara", "female", 50);
AllEmployees[3] = new PartTimeEmployee();

for (int i = 0; i < 4; i++)


{
Console.WriteLine(AllEmployees[i].ToString());
Console.WriteLine("Your pay = " + AllEmployees[i].CalcPay());

Out from above when executed

63
Chapter 8: Miscellaneous

One of the great things about classes is that we can re-use ones that Microsoft has created
for us in the .net library. One useful class for games and simulation is the Random class.

Generating Random Numbers


The Random class defined in the .NET Framework class library provides functionality to
generate random numbers.

The Random class constructors have two overloaded forms. It takes either no value or it
takes a seed value, i.e. a number used to calculate a starting value for the pseudo-random
number sequence.

If a negative number is specified, the absolute value of the number is used.

The Random class has three public methods- Next, NextBytes, and NextDouble.
• The Next method returns a random number, The Next method has three overloaded
forms and allows you to set the minimum and maximum range of the random
number.
• NextBytes returns an array of bytes filled with random numbers, and
• NextDouble returns a random number between 0.0 and 1.0.

Some Examples:

The following code returns a random number:

Random random = new Random();

int num = random.Next();

The following code returns a random number less than 1000.

int num = random.Next(1000);

The following code returns a random number between min and max:

private int RandomNumber(int min, int max)


{

Random random = new Random();

return random.Next(min, max); }

64
Using a seed value

Providing an identical seed value to different Random objects causes each instance to
produce identical sequences of random numbers.

If your application requires different random number sequences, invoke this constructor
repeatedly with different seed values. One way to produce a unique seed value is to make it
time-dependent. For example, derive the seed value from the system clock.

Random random = new Random(Date.Now.Millisecond);

Generic List Class


Another very useful class is the generic list class. We’ll do more on generics in second year
but for now, all we need to know is that we can declare a list of any type of object we want.

• We can Add objects to lists


• We can Remove objects from lists
• We can Count how many things we have in a list
• We can Find things in lists

Lists are like arrays but much easier to use, for example list elements can be accessed using
square brackets like arrays. Lists are not restricted in size, so we can keep on adding things
without worrying.

To use lists we just need to include the using directive at the top of our programme.
using System.Collections.Generic;

We can then declare a list of objects of a class we’ve already written e.g. employees:
List<Employee> employees = new List<Employee>();

We can then add employees to our list once we have them created as before e.g..
Employee employee = new Employee(“Sarah”);
Employees.Add(employee);

65
To think about.
We need a program to compute till receipts as follows:

Sale number : 556

Item Quantity Unit Price Price

Loaf 2 1.50 3.00

Cornflakes 1 2.50 2.50

Litre Milk 3 1.20 3.60

TOTAL 9.10

Payment method Cash

• What classes might you need?


• How could you use a generic list class here?

Hint : A Sale is made up of a sale number, a List of ItemLines, and a payment method. Here
we can have two classes – an ItemLine class ( with attributes item (string), quantity(int) unit
price(decimal) and a method to CalculatePrice) and a Sale class (with the attributes sale
number (int), items (a generic list of ItemLine) and methods to AddItem and
CalculateTotal).

66
Chapter 9 - Software Design Fundamentals

When we move beyond simple problems, our code can get very messy. Fortunately all programming
languages give us ways to break our problem down into smaller pieces. Learning how to do this is a
fundamental skill for software developers.

“Modularity is the degree to which a system’s components are made up of relatively


independent components or parts which can be combined.”

The basic idea is just like Lego - we build software systems out of smaller components, often
called modules.
“Module’ is a general term that can be used to describe any relatively independent software
component. This year we’ll mainly focus on two types of module:

• Methods and
• Classes, which group methods round the data they need.
These give us a way to divide our software into smaller pieces that are easier to reuse and
test.
If we name our modules clearly and carefully, following standards, this will also help us
write clean code that is easy to change and maintain.
Methods
When we write methods we need to be clear about
(i) what goes in
(ii) what comes out
(iii) what value(s) might be changed as the method is executed.

67
Naming methods and parameters clearly and consistently can make our code readable and
clear.

For example, in a Bank Account Class we might have a method to lodge some money, for
example:

decimal Lodge(decimal amount)


{
Balance+=amount
return Balance;
}

Note that the job done is to add the amount to the bank balance, which will be changed as a
result.

UML Diagram of a Bank account class showing methods and attributes.

68
Recap: Using Classes and Methods as Building Blocks to Solve Problems
Classes group methods round data and can be used to model real world entities or objects (
e.g. bank accounts, employees) or things that can be generally useful in programming e.g.
user interface components (Windows, Buttons), random numbers, lists, or even things that
might help create a game (sprites). We can think of these as building blocks that we can
test, adapt and reuse.

• Be clear about the role of each class. Name it by what it represents. Make sure it has
the properties and methods it needs.
• Be clear about the distinct role of each method: the job it does, what data it needs to
do that job (arguments, parameters), and what is returned (if needed). Give the
method a name that closely describes what job it does.

69
70
71

You might also like