- Abstract refers to the fact that while there is an employee class nothing is allowed to simply be an emplyoee. It must be a subclass.
{
// protected data for kids.
protected string fullName;
protected int empID;
protected float currPay;
protected string empSSN;
- Protected means private except to ofspring of the class
// private static data.
private static string companyName;
- Static means that this is fixed for all members of the employee class
// Readonly field (just for example purposes).
public readonly string SSNField;
#region Constructors
// Default ctor.
public Employee(){}
// Custom ctor
public Employee(string FullName, int empID,
float currPay, string ssn)
{
// Assign internal state data.
// Note use of 'this' keyword
// to avoid name clashes.
this.fullName = FullName;
this.empID = empID;
this.currPay = currPay;
this.empSSN = ssn;
// Assign read only field.
SSNField = ssn;
}
// A static ctor (to assign static field)
static Employee()
{companyName = "Intertech, Inc";}
// If the user calls this ctor, forward to the 4-arg version
// using arbitrary values...
public Employee(string fullName)
: this(fullName, 3333, 0.0F, ""){}
- the : is used as if it is sending the data back to itself
#endregion
#region Methods
// Bump the pay for this emp.
public virtual void GiveBonus(float amount)
{currPay += amount;}
// Show state (could use ToString() as well)
public virtual void DisplayStats()
{
Console.WriteLine("Name: {0}", fullName);
Console.WriteLine("Pay: {0}", currPay);
Console.WriteLine("ID: {0}", empID);
Console.WriteLine("SSN: {0}", empSSN);
}
- The
virtual key word here means that subsquent sub class's are able to overide this function.
// Accessor & mutator for the FirstName.
public string GetFullName() { return fullName; }
public void SetFullName(string n)
{
// Remove any illegal characters (!,@,#,$,%),
// check maximum length or case before making assignment.
fullName = n;
}
#endregion
#region properties
// A static property.
public static string Company
{
get { return companyName; }
set { companyName = value;}
}
// Property for the empID.
public int EmpID
{
get {return empID;}
set
{
#if DEBUG
Console.WriteLine("value is an instance of: {0} ", value.GetType());
Console.WriteLine("value as string: {0} ", value.ToString());
#endif
empID = value;
}
}
// Property for the currPay.
public float Pay
{
get {return currPay;}
set {currPay = value;}
}
// Another property for ssn.
public string SSN
{
get { return empSSN; }
}
- This in effect is making the ssn read only.
#endregion
}
}
- From the employee code above we have created an Employee class but forbiden C# from creating an employee only allowing us to create sub class's using the
Abstract key word.
- The
abstract key word can also be used to enforce methods. It dose this by saying all subclass's have to have the method or they cant be created.
- The following is how we woud create subclass called manager
using System;
namespace Employees
{
public class Manager : Employee
- Here we are saying Manager
IS AN Employee.
{
private ulong numberOfOptions;
#region Constructors
public Manager(){}
public Manager(string FullName, int empID,
float currPay, string ssn, ulong numbOfOpts)
: base(FullName, empID, currPay, ssn)
{
// This point of data belongs with us!
numberOfOptions = numbOfOpts;
}
#endregion
#region Methods and properties
public override void GiveBonus(float amount)
{
// Increase salary.
base.GiveBonus(amount);
// And give some new stock options...
Random r = new Random();
numberOfOptions += (ulong)r.Next(500);
}
public override void DisplayStats()
{
base.DisplayStats();
Console.WriteLine("Number of stock options: {0}", numberOfOptions);
}
- The |override | keyword hear means that these functions take over the base functions
public ulong NumbOpts
{
get {return numberOfOptions;}
set { numberOfOptions = value;}
}
#endregion
}
}
- Another key word
sealed can be used and this means that the class can have no "children".
- It is also important to note that each sub class can only have one parent.
public sealed class Manager : Employee
- In dealing with polymorpism we have seen how to use
override and virtual key words. There is one more that is also used. This is the new word it is used in a simalr way as override yet instead of inheriting all the previous logic it starts afresh.
- Having said that it is still possible to access the "parent method".
- Assume for the moment that we have the following hiracy. Shape-->Circle-->Oval.
- With each one having their own draw function using
new except shape which simply has an abstract method
Oval O = new Oval();
((Circle)O).Draw();
- This syntax also comes into play for casting between types.
- Here is code that would create a machine for fireing employees.
public class The Machine
{
// fire everyone >:-)
public static void FireThisPerson(Employee e)
{
// Figure out which type I have using 'is'.
if(e is SalesPerson)
{
Console.WriteLine("-> Lost a sales person named {0}", e.GetFullName());
Console.WriteLine("-> {0} made {1} sales...",
e.GetFullName(), ((SalesPerson)e).NumbSales);
}
if(e is Manager)
{
Console.WriteLine("-> Lost a suit named {0}", e.GetFullName());
Console.WriteLine("-> {0} had {1} stock options...",
e.GetFullName(), ((Manager)e).NumbOpts);
}
}
}
- As we see above we are able to use
is word to test weather an employee is a salesperson or manager.
- But what would happen if the following code was used
object frank = new Manager("Frank Zappa", 9 ,78000, "111-11-1111", 5);
- While this is allowed as a manager is an emplyee which is an object.
- We come into trouble when we try to fire frank
TheMachine.FireThisPerson(frank);
- This will fail as the machine will only accept employee's and not objects.
- To fix this we use the simal syntax we saw earlier.
TheMachine.FireThisPerson((Employee)frank);