We have just mentioned that you can create a new
version of a member in a derived class for a member (property or
method) that already exists in the parent class. After doing this,
when you call that member in your program, you need to make sure
that the right member gets called, the member in the base class or
the equivalent member in the derived class.
When you create a base class, if you anticipate
that a certain member (property or method) would need to be
redefined in the derived class, you can indicate this to the
compiler. On the other hand, while creating your classes, if you
find out that you are customizing a property or a method that
already exists in the base class, you should let the compiler know
that you are providing a new version. In both cases, the common
member should be created as virtual.
To create a virtual member, in the base class,
type the virtual keyword to the left of the property or
method. Based on this, the Area property of our Circle class can be
created as follows:
|
|
class Circle
{
public virtual double Area
{
get
{
return Radius * Radius * 3.14159;
}
}
}
Application:
Using Inheritance With Namespaces
|
|
- Start Microsoft Visual C# 2010 Express or Microsoft Visual Studio
- To create a new application, on the main menu, click File -> New
Project...
- In the middle list, click Empty Project
- Set the Name to Geometry3 and press Enter
- To create a new class, on the main menu, click Project -> Add
Class...
- Set the Name to Square and press Enter
- Change the file as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Geometry3
{
public class Square
{
private double sd;
public Square(double s = 0.00D)
{
this.sd = s;
}
}
}
- To create a new class, on the main menu, click Project -> Add
Class...
- Set the Name to Rectangle and press Enter
- Change the file as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Geometry3
{
public class Rectangle
{
double len;
double hgt;
public Rectangle(double L = 0.00D, double H = 0.00D)
{
this.len = L;
this.hgt = H;
}
}
}
When you derive a class from an abstract class, since
the methods (if any) of the abstract class were not implemented, you must
implement each one of them in the derived class. When customizing virtual
members in a derived class, to indicate that a member is already virtual in
the base class and that you are defining a new version, type the override
keyword to the left of its declaration. For example, the Area property in
our Sphere class can be created as follows:
class Sphere : Circle
{
public override double Area
{
get
{
return 4 * Radius * Radius * 3.14159;
}
}
public double Volume
{
get
{
return 4 * 3.14159 * Radius * Radius * Radius;
}
}
}
In the same way, when implementing an abstract method of
a class, type the override keyword to its left.
Application:
Using Virtual Members
|
|
- To create a new class, on the main menu, click Project -> Add
Class...
- Set the Name to a Descriptor and press Enter
- Change the file as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Geometry3
{
public class Descriptor
{
public virtual string Describe()
{
string Msg = "A quadrilateral is a geometric figure " +
"that has four sides and four angles.";
return Msg;
}
}
}
- Access the Square.cs file and override the Description method as
follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Geometry3
{
public class Square : Descriptor
{
private double sd;
public Square(double s = 0.00D)
{
this.sd = s;
}
public override string Describe()
{
// Get the introduction from the parent
string Introduction = base.Describe() +
"\nA square is a quadrilateral that has four " +
"equal sides and four right angles";
return Introduction;
}
}
}
- Access Rectangle.cs file and change it as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Geometry3
{
public class Rectangle : Descriptor
{
double len;
double hgt;
public Rectangle(double L = 0.00D, double H = 0.00D)
{
this.len = L;
this.hgt = H;
}
public override string Describe()
{
// Get the introduction from the parent
string Introduction = base.Describe();
string msg = Introduction +
"\nA rectangle is a quadrilateral that has adjacent " +
"perpendicular sides. This implies that its four " +
"angles are right.";
return msg;
}
}
}
- To create a new file, on the main menu, click Project -> Add New
Item
- In the middle list, click Code File
- Change the Name to Geometry and press Enter
- Change the file as follows:
using System;
using Geometry3;
public class GeometricFormulas
{
static void DisplaySquare(Square S)
{
Console.WriteLine("Square Characteristics");
Console.WriteLine("Description: {0}", S.Describe());
}
static void DisplayRectangle(Rectangle R)
{
Console.WriteLine("Rectangle Characteristics");
Console.WriteLine("Description: {0}", R.Describe());
}
public static int Main()
{
Square Sq = new Square();
Rectangle Rect = new Rectangle();
Console.Title = "Geometric Figures";
Console.WriteLine("========================================");
DisplaySquare(Sq);
Console.WriteLine("========================================");
DisplayRectangle(Rect);
Console.WriteLine("========================================");
Console.ReadKey();
return 0;
}
}
- To execute the project, press F5. This would produce:
========================================
Square Characteristics
Description: A quadrilateral is a geometric figure that has four
sides and four angles. A square is a quadrilateral that has four equal
sides and four right angles
========================================
Rectangle Characteristics
Description: A quadrilateral is a geometric figure that has four
sides and four angles.
A rectangle is a quadrilateral that has adjacent perpendicular sides.
This implies that its four angles are right.
========================================
- Press Enter to close the DOS window and return to your programming
environment
Creating an Abstract
Class
|
|
In a program, you can create a class whose role is only
meant to provide fundamental characteristics for other classes. This type of
class cannot be used to declare a variable. Such a class is referred to as
abstract. Therefore, an abstract class can be created only to serve as a
parent class for other classes.
To create an abstract class, type the abstract
keyword to the left of its name. Here is an example:
abstract class Ball
{
protected int TypeOfSport;
protected string Dimensions;
}
Application: Creating an Abstract Class
|
|
Abstract Properties and
Methods
|
|
When creating a class that would mainly be used as a
base class for future inheritance, you can create one or more properties and
make them abstract. To do this, when creating the property, type the
abstract keyword to its left. Because you would not define the property,
you can simply type the get keyword and its semi-colon in
the body of the property.
A method of a class also can be made abstract. An
abstract method can be a member of only an abstract class. If you make a
method abstract in a class, you must not implement the method. To create an
abstract method, when creating its class, type the abstract keyword
to the left of the method's name. End the declaration with a semi-colon and
no body for the method since you cannot implement it. Here is an example:
public abstract class Ball
{
protected int TypeOfSport;
protected string Dimensions;
public abstract double CalculateArea();
}
In the same way, you can create as many properties and
methods as you see fit. You can choose what properties and methods to make
abstract. This is important for inheritance.
Application: Creating an Abstract Property
|
|
- To create an abstract property, change the Descriptor class as
follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Geometry3
{
public abstract class Descriptor
{
public abstract string Name { get; }
public virtual string Describe()
{
return "A quadrilateral is a geometric figure " +
"that has four sides and four angles.";
}
}
}
- Access the Square.cs file and change it as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Geometry3
{
public class Square : Descriptor
{
private double sd;
public Square(double s = 0.00D)
{
this.sd = s;
}
public override string Name
{
get { return "Square"; }
}
public override string Describe()
{
// Get the introduction from the parent
string Introduction = base.Describe() +
"\nA square is a quadrilateral that has four " +
"equal sides and four right angles";
return Introduction;
}
}
}
- Access the Rectangle.cs file and change it as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Geometry3
{
public class Rectangle : Descriptor
{
double len;
double hgt;
public Rectangle(double L = 0.00D, double H = 0.00D)
{
this.len = L;
this.hgt = H;
}
public override string Name
{
get { return "Rectangle"; }
}
public override string Describe()
{
// Get the introduction from the parent
string Introduction = base.Describe();
string Msg = Introduction +
"\nA rectangle is a quadrilateral that has adjacent " +
"perpendicular sides. This implies that its four " +
"angles are right.";
return Msg;
}
}
}
- Access the Geometry.cs file and change it as follows:
using System;
using Geometry3;
public class GeometricFormulas
{
static void DisplaySquare(Square S)
{
Console.WriteLine("Square Characteristics");
Console.WriteLine("Name: {0}", S.Name);
Console.WriteLine("Description: {0}", S.Describe());
}
static void DisplayRectangle(Rectangle R)
{
Console.WriteLine("Rectangle Characteristics");
Console.WriteLine("Name: {0}", R.Name);
Console.WriteLine("Description: {0}", R.Describe());
}
public static int Main()
{
Square Sq = new Square();
Rectangle Rect = new Rectangle();
Console.Title = "Geometric Figures";
Console.WriteLine("========================================");
DisplaySquare(Sq);
Console.WriteLine("========================================");
DisplayRectangle(Rect);
Console.WriteLine("========================================");
Console.ReadKey();
return 0;
}
}
- Press F5 to execute the project. This would produce:
========================================
Square Characteristics
Name: Square
Description: A quadrilateral is a geometric figure that has four
sides and four angles. A square is a quadrilateral that has four equal
sides and four right angles
========================================
Rectangle Characteristics
Name: Rectangle
Description: A quadrilateral is a geometric figure that has four sides
and four angles.
A rectangle is a quadrilateral that has adjacent perpendicular sides.
This implies that its four angles are right.
========================================
- Press Enter to close the DOS window and return to your programming
environment
Details on Abstract and
Virtual Members of a Class
|
|
We saw that, if you create a method marked as abstract
in the body of a class, the method must not have a body. Here is an example:
public abstract class Triangle
{
private double bs;
private double hgt;
public Triangle()
{
this.bs = 0.00D;
this.hgt = 0.00D;
}
public abstract double Area();
}
If you want to define the method, that is, if you want
the method to have a body, you must mark it with the virtual
keyword. Here is an example:
public abstract class Triangle
{
private double bs;
private double hgt;
public Triangle()
{
this.bs = 0.00D;
this.hgt = 0.00D;
}
public virtual double Area()
{
return this.bs * this.hgt / 2;
}
}
We also saw that you can make a property abstract. If
the property has only a get accessor, it must use the
abstract keyword. Here is an example:
public abstract class Triangle
{
private double bs;
private double hgt;
public Triangle()
{
this.bs = 0.00D;
this.hgt = 0.00D;
}
public abstract double Perimeter { get; }
public virtual double Area()
{
return this.bs * this.hgt / 2;
}
}
If the property has both a get and a
set accessors, it can use either the abstract
or the virtual keyword. Here are examples:
public abstract class Triangle
{
private double bs;
private double hgt;
public Triangle()
{
this.bs = 0.00D;
this.hgt = 0.00D;
}
public abstract double Median { get; set; }
public virtual double Perimeter { get; set; }
public virtual double Area()
{
return this.bs * this.hgt / 2;
}
}
|
|