.NET 1.1+

# C# Abstract Classes

*The twentieth part of the C# Object-Oriented Programming tutorial investigates the use of abstract classes. These are special classes that are designed to be used only as base classes for inheritance. They do not permit the instantiation of objects.*

## Inheriting from an Abstract Class

Deriving a subclass from an abstract class is almost identical to inheriting from any other class. The only difference is that the abstract members of the base class must be implemented.

In the three-dimensional object example we will create two subclasses of ThreeDObject. The first will represent cubes and the second will permit the creation of spheres. Each of the classes will implement the property and the method that have been created as abstract members in the ThreeDObject class.

To begin, add two new class files to the project. Create one class file for the "Cube" class and a second for the "Sphere" class. After you have added the two new classes, modify the code so that they inherit from the ThreeDObject class by appending a colon character (:) and the base class name to each declaration.

The code for the classes should be as follows:

// Cube.cs class Cube : ThreeDObject { } // Sphere.cs class Sphere : ThreeDObject { }

If you attempt to compile the program, you will receive four compiler errors. These indicate that the abstract property and method must be implemented in each subclass.

### Implementing the Abstract Members

To complete the two subclasses, the functionality of the abstract members of the superclass must be defined. This is achieved by *overriding* the abstract elements using the override keyword.

To calculate the surface area of a cube, the height is squared to calculate the area of a single face. The result is then multiplied by six to include all six faces. The volume of a cube is simply the height cubed. To add these calculations whilst overriding the abstract members, add the following code to the Cube class:

public override double SurfaceArea { get { return Math.Pow(Height, 2) * 6; } } public override double CalculateVolume() { return Math.Pow(Height, 3); }

The calculations for a sphere are slightly more complex as they use the value of *Pi* (). This value can be retrieved from the "Math" class. The formula for the surface area of a sphere is 4r2 where "r" is the radius of the sphere. In our example's case, the radius is half of the Height property value. The formula for the volume of a sphere is 4/3r3.

To add these calculations, add the following code to the sphere class:

public override double SurfaceArea { get { return 4 * Math.PI * Math.Pow(Height / 2, 2); } } public override double CalculateVolume() { return (4 / 3) * Math.PI * Math.Pow(Height / 2, 3); }

### Testing the Subclasses

We can now test the two subclasses using the Program class and the Main method. To perform a test of the abstract and concrete members of the base class and the overridden members of the Cube and Sphere classes we will create a simple static method that outputs all of the dimensions provided by ThreeDObject. We will call this twice from the Main method, firstly for a cube and then for a sphere. Here is the code required in the Program class and the expected output:

static void Main() { Cube cube = new Cube(); cube.Height = 2.5; OutputDimensions("Cube", cube); Sphere sphere = new Sphere(); sphere.Height = 2.5; OutputDimensions("Sphere", sphere); } static void OutputDimensions(string name, ThreeDObject object3D) { Console.WriteLine(); Console.WriteLine(name); Console.WriteLine("Height\t{0:f2}m", object3D.Height); Console.WriteLine("Area\t{0:f2}m2", object3D.SurfaceArea); Console.WriteLine("Volume\t{0:f2}m3", object3D.CalculateVolume()); Console.WriteLine("V:A\t{0:f2}", object3D.CalculateVolumeToAreaRatio()); } /* OUTPUT Cube Height 2.50m Area 37.50m2 Volume 15.63m3 V:A 0.42 Sphere Height 2.50m Area 19.63m2 Volume 6.14m3 V:A 0.31 */