Wednesday, August 29, 2007

Virtual Methods in C#

Earlier in the notes, an example: inheritance5.cs was shown where both the base class and the derived class both have methods with the same name and signature. As was seen, this was permitted by the compiler but a warning error was issued. To overcome this warning error, the modifier new was used in the example: inheritance3.cs on the derived class' method to inform the compiler that the definition of the derived class' method was hiding the base class' method. This example also compiled and ran but there were no warning errors.

Sometimes it is desirable to force the derived class to either use the base class' method or to override the base class' method with an entirely different method but with the same name. In either case the base class' method must have the modifier: virtual. When this modifier is used, then the modifier new may not be used. Instead the modifier override must be used if the derived class is to have a method with the same name as the base class. To see an example where the base class is using the modifier virtual but the derived class does not use these names see: inheritance7.cs. To see an example where the base class uses the modifier virtual and the derived class defines methods with the same name by using the modifier: override see: inheritance6.cs. Recall how when the ToString() method was discussed in a previous section, that the modifier override was used. The reason for this is that the method ToString() is a virtual method of the class: System.Object.


// program_id inheritance1.cs
// written?_by don voils
// date_written 12/11/2006
// description This program demonstrates how
// to use inheritance.
//

using System;

class theProgram
{
public class Customer
{
private string CustomerID;
private string CustomerName;
private string CustomerAddress;
private string CustomerCity;
private string CustomerState;
private string CustomerZipCode;

public void setCustomerID(string ID)
{
CustomerID = ID;
}
public void setCustomerName(string Name)
{
CustomerName = Name;
}
public void setCustomerAddress(string Address)
{
CustomerAddress = Address;
}
public void setCustomerCity(string City)
{
CustomerCity = City;
}
public void setCustomerState(string State)
{

CustomerState = State;
}
public void setCustomerZipCode(string Code)
{
CustomerZipCode = Code;
}
public string getCustomerID()
{
return CustomerID;
}
public string getCustomerName()
{
return CustomerName;
}
public string getCustomerAddress()
{
return CustomerAddress;
}
public string getCustomerCity()
{
return CustomerCity;
}
public string getCustomerState()
{
return CustomerState;
}
public string getCustomerZipCode()
{
return CustomerZipCode;
}
}

public class Invoice : Customer
{
private decimal InvoiceAmount;

public void setInvoiceAmount(decimal Amount)
{
InvoiceAmount = Amount;
}
public decimal getInvoiceAmount()
{
return InvoiceAmount;

}
}
static void Main()
{
Invoice theTransaction = new Invoice();
Console.Write("What is the customer's ID? ");
theTransaction.setCustomerID(Console.ReadLine());

Console.Write("What is the customer's name? ");
theTransaction.setCustomerName(Console.ReadLine());

Console.Write("What is the customer's address? ");
theTransaction.setCustomerAddress(Console.ReadLine());

Console.Write("What is the customer's city? ");
theTransaction.setCustomerCity(Console.ReadLine());

Console.Write("What is the customer's state? ");
theTransaction.setCustomerState(Console.ReadLine());

Console.Write("What is the customer's zip code? ");
theTransaction.setCustomerZipCode(Console.ReadLine());

Console.Write("What is the amount of the invoice? ");
theTransaction.setInvoiceAmount(Decimal.Parse(Console.ReadLine()));

Console.Clear();

Console.WriteLine("Customer ID: {0}", theTransaction.getCustomerID());
Console.WriteLine("Customer Name: {0}", theTransaction.getCustomerName());
Console.WriteLine("Customer Address: {0}", theTransaction.getCustomerAddress());
Console.WriteLine("Customer City: {0}", theTransaction.getCustomerCity());
Console.WriteLine("Customer State: {0}", theTransaction.getCustomerState());
Console.WriteLine("Customer Zip Code: {0}", theTransaction.getCustomerZipCode());
Console.WriteLine("Invoice Amount: {0,15:c}\n\n", theTransaction.getInvoiceAmount());
Console.ReadKey();
}


}



// program_id inheritance2.cs
// written?_by don voils
// date_written 12/11/2006
// description This program demonstrates how
// to use inheritance.
//

using System;

class theProgram
{
public class People
{
private string PeopleID;
private string PeopleName;
private string PeopleAddress;
private string PeopleCity;
private string PeopleState;
private string PeopleZipCode;

public void setPeopleID(string ID)
{
PeopleID = ID;
}
public void setPeopleName(string Name)
{
PeopleName = Name;
}
public void setPeopleAddress(string Address)
{
PeopleAddress = Address;
}
public void setPeopleCity(string City)
{
PeopleCity = City;
}
public void setPeopleState(string State)
{

PeopleState = State;
}
public void setPeopleZipCode(string Code)
{
PeopleZipCode = Code;
}
public string getPeopleID()
{
return PeopleID;
}
public string getPeopleName()
{
return PeopleName;
}
public string getPeopleAddress()
{
return PeopleAddress;
}
public string getPeopleCity()
{
return PeopleCity;
}
public string getPeopleState()
{
return PeopleState;
}
public string getPeopleZipCode()
{
return PeopleZipCode;
}
}
public class Employee : People
{
private char PayType;
private decimal PayRate;
private decimal GrossPay;
public void setPayType(char Type)
{
PayType = Type;
}
public char getPayType()
{
return PayType;

}
public void setPayRate(decimal Rate)
{
PayRate = Rate;
}
public decimal getPayRate()
{
return PayRate;
}
public void setGrossPay(decimal Amount)
{
GrossPay = Amount;
}
public decimal getGrossPay()
{
return GrossPay;
}
}
public class Customer : People
{
private decimal BalancetDue;

public void setBalanceDue(decimal Amount)
{
BalancetDue = Amount;
}
public decimal getBalanceDue()
{
return BalancetDue;
}
}
public class Vendor : People
{
private decimal AmountOwed;

public void setAmountOwed(decimal Amount)
{
AmountOwed = Amount;
}
public decimal getAmountOwed()
{
return AmountOwed;
}

}
static void Main()
{
bool processAgain = true;
while (processAgain == true)
{
Console.WriteLine(" Account Type\n");
Console.WriteLine(" 1. Employee");
Console.WriteLine(" 2. Customer");
Console.WriteLine(" 3. Vendor");
Console.Write("\n Which? ");
char TransactionType = Char.Parse(Console.ReadLine());
Console.Clear();
switch (TransactionType)
{
case '1':
processEmployee();
break;
case '2':
processCustomer();
break;
case '3':
processVendor();
break;
default:
Console.WriteLine("You selected an incorrect type." +
"Please try again.\n");
break;
}
Console.Write("\nDo you want to process another? Y or N ");
TransactionType = Char.Parse(Console.ReadLine());
Console.Clear();
if ((TransactionType != 'y') && (TransactionType != 'Y'))
processAgain = false;
else
processAgain = true;
}
}

static void processEmployee()
{
Employee theTransaction = new Employee();
Console.Write("What is the employee's ID? ");

theTransaction.setPeopleID(Console.ReadLine());

Console.Write("What is the employee's name? ");
theTransaction.setPeopleName(Console.ReadLine());

Console.Write("What is the employee's address? ");
theTransaction.setPeopleAddress(Console.ReadLine());

Console.Write("What is the employee's city? ");
theTransaction.setPeopleCity(Console.ReadLine());

Console.Write("What is the employee's state? ");
theTransaction.setPeopleState(Console.ReadLine());

Console.Write("What is the employee's zip code? ");
theTransaction.setPeopleZipCode(Console.ReadLine());

char theType;
do
{
Console.Write("What is the employee's pay type (H:Hourly or S:Salaried? ");
theType = Char.Parse(Console.ReadLine());
} while ((theType != 'H') && (theType != 'h') && (theType != 'S') && (theType != 's'));
theTransaction.setPayType(theType);

Console.Write("What is the employee's pay rate? ");
theTransaction.setPayRate(Decimal.Parse(Console.ReadLine()));

Console.Write("What is the employee's gross pay? ");
theTransaction.setGrossPay(Decimal.Parse(Console.ReadLine()));
Console.WriteLine("\n\n");

Console.Clear();
Console.WriteLine("Employee ID: {0}", theTransaction.getPeopleID());
Console.WriteLine("Employee Name: {0}", theTransaction.getPeopleName());
Console.WriteLine("Employee Address: {0}", theTransaction.getPeopleAddress());
Console.WriteLine("Employee City: {0}", theTransaction.getPeopleCity());
Console.WriteLine("Employee State: {0}", theTransaction.getPeopleState());
Console.WriteLine("Employee Zip Code: {0}", theTransaction.getPeopleZipCode());
Console.WriteLine("Employee Pay Type: {0}", theTransaction.getPayType());
Console.WriteLine("Employee Pay Rate: {0,15:c}", theTransaction.getPayRate());
Console.WriteLine("Employee Gross Pay: {0,15:c}", theTransaction.getGrossPay());
Console.WriteLine("\n\n");

}

static void processCustomer()
{
Customer theTransaction = new Customer();
Console.Write("What is the customer's ID? ");
theTransaction.setPeopleID(Console.ReadLine());

Console.Write("What is the customer's name? ");
theTransaction.setPeopleName(Console.ReadLine());

Console.Write("What is the customer's address? ");
theTransaction.setPeopleAddress(Console.ReadLine());

Console.Write("What is the customer's city? ");
theTransaction.setPeopleCity(Console.ReadLine());

Console.Write("What is the customer's state? ");
theTransaction.setPeopleState(Console.ReadLine());

Console.Write("What is the customer's zip code? ");
theTransaction.setPeopleZipCode(Console.ReadLine());

Console.Write("What is the cutomer's balance due? ");
theTransaction.setBalanceDue(Decimal.Parse(Console.ReadLine()));
Console.WriteLine("\n\n");

Console.Clear();
Console.WriteLine("Customer ID: {0}", theTransaction.getPeopleID());
Console.WriteLine("Customer Name: {0}", theTransaction.getPeopleName());
Console.WriteLine("Customer Address: {0}", theTransaction.getPeopleAddress());
Console.WriteLine("Customer City: {0}", theTransaction.getPeopleCity());
Console.WriteLine("Customer State: {0}", theTransaction.getPeopleState());
Console.WriteLine("Customer Zip Code: {0}", theTransaction.getPeopleZipCode());
Console.WriteLine("Cusomter Balance Due: {0,15:c}", theTransaction.getBalanceDue());
Console.WriteLine("\n\n");
}


static void processVendor()
{
Vendor theTransaction = new Vendor();
Console.Write("What is the vendor's ID? ");

theTransaction.setPeopleID(Console.ReadLine());

Console.Write("What is the vendor's name? ");
theTransaction.setPeopleName(Console.ReadLine());

Console.Write("What is the vendor's address? ");
theTransaction.setPeopleAddress(Console.ReadLine());

Console.Write("What is the vendor's city? ");
theTransaction.setPeopleCity(Console.ReadLine());

Console.Write("What is the vendor's state? ");
theTransaction.setPeopleState(Console.ReadLine());

Console.Write("What is the vendor's zip code? ");
theTransaction.setPeopleZipCode(Console.ReadLine());

Console.Write("What is the amount owed the vendor? ");
theTransaction.setAmountOwed(Decimal.Parse(Console.ReadLine()));
Console.WriteLine("\n\n");

Console.Clear();
Console.WriteLine("Vendor ID: {0}", theTransaction.getPeopleID());
Console.WriteLine("Vendor Name: {0}", theTransaction.getPeopleName());
Console.WriteLine("Vendor Address: {0}", theTransaction.getPeopleAddress());
Console.WriteLine("Vendor City: {0}", theTransaction.getPeopleCity());
Console.WriteLine("Vendor State: {0}", theTransaction.getPeopleState());
Console.WriteLine("Vendor Zip Code: {0}", theTransaction.getPeopleZipCode());
Console.WriteLine("Amount Owed: {0,15:c}", theTransaction.getAmountOwed());
Console.WriteLine("\n\n");
}
}



// program_id inheritance3.cs
// written_by don voils
// date_written 10/2/2006
// description In this example the base class has a
// protected attribute that is accessible
// in the derived class. In addition the
// derived class has methods with the
// same name as the base class and overcomes
// this restriction by using the keyword word: new.
//

using System;

namespace constructor
{
class stuff
{
protected int member;

public void setMember(int a)
{
member = a;
Console.WriteLine("Through the stuff class using the setMember() method.\n");
}

public void print()
{
Console.WriteLine("Through the stuff class using the print() method: member = {0}.\n", member);
}
}

class stuff1 : stuff
{
public new void setMember(int a)
{
member = a;
Console.WriteLine("Through the class stuff1 using the setMember() method.\n");
}

public new void print()
{
Console.WriteLine("Through the class stuff1 using the print() method: member = {0}.\n", member);
}
}

class myProgram
{
static void Main()
{
Console.WriteLine("Defining theObject an object of the class stuff.\n");

stuff theObject = new stuff();

theObject.setMember(10);

theObject.print();

Console.WriteLine("\n\n");

Console.WriteLine("Defining object1 an object of the class stuff1.\n");

stuff1 object1 = new stuff1();

object1.setMember(15);

object1.print();

Console.WriteLine("\n\n");
Console.ReadKey();
}
}
}



// program_id inheritance4.cs
// written?_by don voils
// date_written 12/11/2006
// description This program demonstrates how
// to prevent inheritance. The program is
// the same as inheritance1.cs except
// the class Customer is sealed. The
// program inheritance1.cs compiled and
// ran but this program will not.
//

using System;

class theProgram
{
sealed public class Customer
{
private string CustomerID;
private string CustomerName;
private string CustomerAddress;
private string CustomerCity;
private string CustomerState;
private string CustomerZipCode;

public void setCustomerID(string ID)
{
CustomerID = ID;
}
public void setCustomerName(string Name)
{
CustomerName = Name;
}
public void setCustomerAddress(string Address)
{
CustomerAddress = Address;
}
public void setCustomerCity(string City)
{

CustomerCity = City;
}
public void setCustomerState(string State)
{
CustomerState = State;
}
public void setCustomerZipCode(string Code)
{
CustomerZipCode = Code;
}
public string getCustomerID()
{
return CustomerID;
}
public string getCustomerName()
{
return CustomerName;
}
public string getCustomerAddress()
{
return CustomerAddress;
}
public string getCustomerCity()
{
return CustomerCity;
}
public string getCustomerState()
{
return CustomerState;
}
public string getCustomerZipCode()
{
return CustomerZipCode;
}
}

public class Invoice : Customer
{
private decimal InvoiceAmount;

public void setInvoiceAmount(decimal Amount)
{
InvoiceAmount = Amount;

}
public decimal getInvoiceAmount()
{
return InvoiceAmount;
}
}
static void Main()
{
Invoice theTransaction = new Invoice();
Console.Write("What is the customer's ID? ");
theTransaction.setCustomerID(Console.ReadLine());

Console.Write("What is the customer's name? ");
theTransaction.setCustomerName(Console.ReadLine());

Console.Write("What is the customer's address? ");
theTransaction.setCustomerAddress(Console.ReadLine());

Console.Write("What is the customer's city? ");
theTransaction.setCustomerCity(Console.ReadLine());

Console.Write("What is the customer's state? ");
theTransaction.setCustomerState(Console.ReadLine());

Console.Write("What is the customer's zip code? ");
theTransaction.setCustomerZipCode(Console.ReadLine());

Console.Write("What is the amount of the invoice? ");
theTransaction.setInvoiceAmount(Decimal.Parse(Console.ReadLine()));

Console.Clear();

Console.WriteLine("Customer ID: {0}", theTransaction.getCustomerID());
Console.WriteLine("Customer Name: {0}", theTransaction.getCustomerName());
Console.WriteLine("Customer Address: {0}", theTransaction.getCustomerAddress());
Console.WriteLine("Customer City: {0}", theTransaction.getCustomerCity());
Console.WriteLine("Customer State: {0}", theTransaction.getCustomerState());
Console.WriteLine("Customer Zip Code: {0}", theTransaction.getCustomerZipCode());
Console.WriteLine("Invoice Amount: {0,15:c}", theTransaction.getInvoiceAmount());
Console.WriteLine("\n\n");
}

}



// program_id inheritance5.cs
// written_by don voils
// date_written 10/2/2006
// description This example is contains two class
// one of which is derived from the other.
// The base class and the derived class contain
// methods with the same name. While the program
// compiles and runs, it contains several warning
// error notifying the programmer that the two
// classes have methods with the same names.
//

using System;

namespace constructor
{
class stuff
{
protected int member;

public void setMember(int a)
{
member = a;
Console.WriteLine("Through the stuff class using the setMember() method.\n");
}

public void print()
{
Console.WriteLine("Through the stuff class using the print() method: member = {0}.\n"
, member);
}
}

class stuff1 : stuff
{
// has the same name as a method in the base class.
//
public void setMember(int a)

{
member = a;
Console.WriteLine("Through the class stuff1 using the setMember() method.\n");
}

// has the same name as a method in the base class.
public void print()
{
Console.WriteLine("Through the class stuff1 using the print() method: member = {0}.\n",
member);
}
}

class myProgram
{
static void Main()
{
Console.WriteLine("Defining theObject an object of the class stuff.\n");

stuff theObject = new stuff();

theObject.setMember(10);

theObject.print();

Console.WriteLine("\n\n");

Console.WriteLine("Defining object1 an object of the class stuff1.\n");

stuff1 object1 = new stuff1();

object1.setMember(15);

object1.print();

Console.WriteLine("\n\n");
Console.ReadKey();
}
}
}



// program_id inheritance6.cs
// written_by don voils
// date_written 10/2/2006
// description In this example the base class has a
// protected attribute that is accessible
// in the derived class.
//
// In addition the derived class has methods with the
// same name as the base class. This overcomes
// this restriction by using the keyword words: virtual
// in the base class and overridden in the derived class.
//

using System;

namespace theProgram
{
class theBase
{
protected int member;

virtual public void setMember(int a)
{
member = a;
Console.WriteLine("Through the theBase class using the setMember() method.\n");
}

virtual public void print()
{
Console.WriteLine("Through the theBase class using the print() method: member = {0}.\n", member);
}
}

// Notice that the attribute member of theBase class was
// declared as protected, therefore it is accessible in the
// derived class as though it was a private attribute
// of the derived class.
//
class theDerived : theBase
{

override public void setMember(int a)
{
member = a;
Console.WriteLine("Through the class theDerived using setMember() method.\n");
}

override public void print()
{
Console.WriteLine("Through the class theDerived using print() method: member = {0}.\n", member);
}
}

class myProgram
{
static void Main()
{
Console.WriteLine("Defining theBaseObject an object of the class theBase.\n");

theBase theBaseObject = new theBase();

theBaseObject.setMember(10);

theBaseObject.print();

Console.WriteLine("\n\n");

Console.WriteLine("Defining theDerivedObject an object of the class theDerived.\n");

theDerived theDerivedObject = new theDerived();

theDerivedObject.setMember(15);

theDerivedObject.print();

Console.WriteLine("\n\n");
Console.ReadKey();
}
}
}



// program_id inheritance7.cs
// written_by don voils
// date_written 10/2/2006
// description In this example the base class has a
// methods that are declared as virtual.
// The derived class does not have methods
// by these names. However the program
// compiles and runs.
//

using System;

namespace theProgram
{
class theBase
{
protected int member;

virtual public void setMember(int a)
{
member = a;
Console.WriteLine("Through the theBase class using the setMember() method.\n");
}

virtual public void print()
{
Console.WriteLine("Through the theBase class using the print() method: member = {0}.\n", member);
}
}

class theDerived : theBase
{

}

class myProgram
{
static void Main()
{
Console.WriteLine("Defining theBaseObject an object of the class theBase.\n");

theBase theBaseObject = new theBase();

theBaseObject.setMember(10);

theBaseObject.print();

Console.WriteLine("\n\n");

Console.WriteLine("Defining theDerivedObject an object of the class theDerived.\n");

theDerived theDerivedObject = new theDerived();

theDerivedObject.setMember(15);

theDerivedObject.print();

Console.WriteLine("\n\n");
Console.ReadKey();
}
}
}

No comments: