Fine-Tuning Classes
In Lesson 24 you learned how to build constructors and destructors, special methods that
execute when an object is created or destroyed. In this lesson you learn about other special
methods you can give a class. You learn how to overload and override class methods.
OVERLOADING METHODS
Lesson 24 mentioned that you can give a class any number of constructors as long as they have
different parameter lists. For example, it’s common to give a class a parameterless constructor
that takes no parameters and one or more other constructors that take parameters.
Making multiple methods with the same name but different parameter lists is called overloading.
C# uses the parameter list to decide which version to use when you invoke the method.
For example, suppose you’re building a course assignment application and you have built
Student, Course, and Instructor classes. You could give the Student class two versions of
the
Enroll method, one that takes as a parameter the name of the class in which the student
should be enrolled and a second that takes a
Course object as a parameter.
You could give the
Instructor class similar versions of the Teach method to make the
instructor teach a class by name or
Course object.
Finally, you could give the
Course class different Report methods that:
Display a report in a dialog if there are no parameters
Append a report to the end of a file if the method receives a
FileStream as a parameter
Save the report into a new file if the method receives a
string (the file name) as
a parameter
Making overloaded methods is so easy that there’s little else to say. Just remember to give each
version of the method different kinds of parameters.
25
596906c25.indd 301 4/7/10 12:33:57 PM
302
LESSON 25 Fine-Tuning Classes
OVERRIDING METHODS
When a class inherits from another you can add new properties, methods, and events to the new
class to give it new features that were not provided by the parent class.
Once in a while it’s also useful to replace a method provided by the parent class with a new version.
This is called overriding the parent’s method.
Before you can override a method, you should mark the method in the parent class with the
virtual
keyword so it allows itself to be overridden. Next add the keyword
override to the derived class’s
version of the method to indicate that it overrides the parent class’s version.
For example, suppose the
Person class defines the usual assortment of properties: FirstName,
LastName, Street, City, and so on. Suppose it also provides the following GetAddress function
that returns the
Persons name and address formatted for printing on an envelope:
// Return the Person’s address.
public virtual string GetAddress()
{
return FirstName + “ “ + LastName + “ ” +
Street + “ ” + City + “ “ + State + “ “ + Zip;
}
Now suppose you derive the Employee class from Person. An Employees address looks just like a
Persons except it also includes MailStop. The MailStop property was added by the Employee class
to indicate where to deliver mail within the company.
The following code shows how the
Employee class can override the GetAddress function to return
an
Employee-style address:
// Return the Employee’s address.
public override string GetAddress()
{
return base.GetAddress() + “ ” + MailStop;
}
Notice how the function calls the base class’s version of GetAddress to reuse that version of the
function and avoid duplicated work.
IntelliSense can help you build overridden methods. For example, when you type
“public override” and a space in the
Employee class, IntelliSense lists the virtual
methods that you might be trying to override. If you select one, IntelliSense fills
in a default implementation for the new method. The following code shows the
code IntelliSense generated for the
GetAddress function:
public override string GetAddress()
{
return base.GetAddress();
}
596906c25.indd 302 4/7/10 12:33:57 PM
Overriding Methods
303
The most miraculous thing about overriding a virtual method is that the object uses the method
even if you invoke it from the base class. For example, suppose you have a
Person variable pointing
to an
Employee object. Remember that an Employee is a kind of Person so a Person variable can
refer to an
Employee as in the following code:
Employee bob = new Employee();
Person bobAsAPerson = bob;
Now if the code calls bobAsAPerson.GetAddress(), the result is the Employee version of
GetAddress.
You can think of the virtual keyword as making a slot in the base class for
the method. When you override the method, the derived class fills this slot with
a new version of the method. Now even if you call the method from the base
class, it uses whatever is in the slot.
Overriding a class’s ToString function is particularly useful. All classes inherit a ToString
method from
System.Object, the ultimate ancestor of all other classes, but the default imple-
mentation of
ToString isn’t always useful. By default, for classes that you defined such as
Person and Employee, ToString returns the class’s name.
For example, in the ListPeople program the
Employee class’s ToString function returns “ListPeople.
Employee.” Though this correctly reports the objects class, it might be nice if it returned something
that contained information about the object’s properties. In this example, it might be nice if it returned
the
Employee object’s first and last names.
The following code shows how you can override the
ToString function to return an Employee’s
rst and last name:
// Return first and last name.
public override string ToString()
{
return FirstName + “ “ + LastName;
}
This makes more sense. Now your program can use an Employee object’s ToString method to learn
about the object.
Overriding
ToString also has a nice side benefit for Windows Forms development. Certain controls
and parts of Visual Studio use an objects
ToString method to decide what to display. For example,
the
ListBox and ComboBox controls display lists of items. If those items are not simple strings, the
controls use the items’
ToString methods to generate output.
596906c25.indd 303 4/7/10 12:33:58 PM
304
LESSON 25 Fine-Tuning Classes
If the list is full of Employee objects and you’ve overridden the Employee
class’s
ToString method, then a ListBox or ComboBox can display the
employeesnames.
The ListPeople example program shown in Figure 25-1 (and available as
part of this lessons code download) demonstrates method overriding.
When it starts, the ListPeople program uses the following code to fill its
ListBox with two Student objects and two Employee objects. Both of
these classes inherit from
Person.
private void Form1_Load(object sender, EventArgs e)
{
// Make some people.
peopleListBox.Items.Add(new Student(“Ann”, “Archer”, “101 Ash Ave”,
“Debugger”, “NV”, “72837”));
peopleListBox.Items.Add(new Student(“Bob”, “Best”, “222 Beach Blvd”,
“Debugger”, “NV”, “72837”));
peopleListBox.Items.Add(new Employee(“Cat”, “Carter”, “300 Cedar Ct”,
“Debugger”, “NV”, “72837”, “MS-1”));
peopleListBox.Items.Add(new Employee(“Dan”, “Dental”, “404 Date Dr”,
“Debugger”, “NV”, “72837”, “MS-2”));
}
The Employee class overrides its ToString method so you can see the Employees’ names in
Figure 25-1 instead of their class names. The
Student class does not override its ToString method
so Figure 25-1 shows class names for the
Student objects.
If you select a person in this program and click the Show Address button, the program executes the
following code:
// Display the selected Person’s address.
private void showAddressButton_Click(object sender, EventArgs e)
{
Person person = (Person)peopleListBox.SelectedItem;
if (person != null) MessageBox.Show(person.GetAddress());
}
This code casts the ListBoxs selected item into a Person object. The item is actually either a Student
or an
Employee but those both of those inherit from Person (they are kinds of Person) so the program
can treat them as
Persons.
If the
Person is not null, then something was selected. The program calls the object’s GetAddress
function and displays the result. If the object was actually a
Student, the result is a basic name and
address. If the object was actually an
Employee, the result is a name and address plus mailstop.
In addition to
ListBoxes and ComboBoxes, some parts of Visual Studio use an object’s ToString
method, too. For example, if you stop an executing program and hover the mouse over an object in
the debugger, a tooltip appears that displays the results of the object’s
ToString function. Similarly
if you type an objects name in the Immediate window and press [Enter], the result is whatever is
returned by the object’s
ToString method.
FIGURE 251
596906c25.indd 304 4/7/10 12:33:58 PM
Try It
305
TRY IT
In this Try It, you build a simple drawing application. You build a Shape class to represent a
drawn shape and then derive the
ShapeRectangle and ShapeEllipse classes from that one.
You give the
Shape class a virtual Draw method that takes as a parameter a Graphics object and draws
the shape on the object. The
Shape class’s version of Draw simply draws a rectangle with a big X in it.
You make the
ShapeRectangle and ShapeEllipse classes override Draw to produce their own shapes.
Finally, you add overloaded versions of
Draw that take pen and brush objects as parameters to use
when drawing.
You can download the code and resources for this Try It from the book’s web
page at
www.wrox.com or www.CSharpHelper.com/24hour.html. You can find
the programs in the Lesson25 folder.
Lesson Requirements
Start a new program and create the
Shape class.
Give the class a
using System.Drawing directive.
Give the class a property named
Bounds of type Rectangle. A Rectangle has proper-
ties
X, Y, Width, and Height.
Make a constructor that takes
x, y, width, and height parameters and uses them to
initialize the
Bounds property.
Make a virtual
Draw method that takes three parameters of type Graphics, Pen, and
Brush. Make this method draw a box with an X in it on the Graphics object using
the
Pen and Brush.
Make a virtual overloaded
Draw method that takes only a Graphics object as a
parameter. Make it invoke the other
Draw method, passing it the pen and brush
Pens.Red and Brushes.Transparent.
Derive the
ShapeRectangle class from the Shape class.
Make a constructor that takes
x, y, width, and height parameters and invokes the
base class’s constructor.
Override the
Shape class’s version of the Draw method that takes four parameters so
it draws a rectangle.
Override the second
Draw method so it calls the first, passing it the pen and brush
Pens.Black and Brushes.Transparent.
Repeat the previous steps for the
ShapeEllipse class.
In the main form, create a
List<Shape>.
596906c25.indd 305 4/7/10 12:33:59 PM
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.35.54