An abstract class is one whose role is only meant to
lay a foundation for other classes that would need a common behavior or similar
characteristics. Therefore, an abstract class is used only as a base class for
inheritance. A class is made abstract by declaring its methods as "pure" virtual
methods.
Only a virtual method can be made "pure". The
syntax of declaring a pure virtual method is:
virtual ReturnType MethodName() = 0;
The virtual keyword is required to make sure that a
(any) child of this class can implement this method as it judges it necessary. The ReturnType
is the data type that the method will return. The MethodName is an
appropriate name for the method. The = 0 expression is required to let the compiler
know that this method is pure virtual.
When creating an abstract class, you can declare all of its
methods as pure. Here is an example:
public ref class CQuadrilateral
{
public:
virtual double Perimeter() = 0;
virtual double Area() = 0;
};
To indicate that the class is
abstract, type the abstract keyword after its name. Here is an example:
public ref class CQuadrilateral abstract
{
public:
virtual double Perimeter() = 0;
virtual double Area() = 0;
};
In C++/CLI, if you omit the abstract keyword, you
would receive a warning.
Not all methods of an abstract class have to be pure
virtual. This means that regular virtual methods can also be members of an
abstract class. Here is an example:
public ref class CQuadrilateral abstract
{
public:
virtual String ^ Description();
virtual double Perimeter() = 0;
virtual double Area() = 0;
virtual void Display() = 0;
};
A property can also be a member of an abstract class. If you
declare a property in an abstract class, don't use the = 0 expression on the
property. Here is an example:
public ref class CQuadrilateral abstract
{
public:
virtual property double Base;
virtual String ^ Description();
virtual double Perimeter() = 0;
virtual double Area() = 0;
virtual void Display() = 0;
};
You can also add regular member variables in an abstract
class. You can even make some private, some public, and some protected. Here are
examples:
public ref class CQuadrilateral abstract
{
private:
double bs;
protected:
String ^ Name;
public:
virtual property double Base;
virtual String ^ Description();
virtual double Perimeter() = 0;
virtual double Area() = 0;
virtual void Display() = 0;
};
An abstract class can also have one or more constructors:
public ref class CQuadrilateral abstract
{
private:
double bs;
protected:
String ^ Name;
public:
virtual property double Base;
virtual String ^ Description();
virtual double Perimeter() = 0;
virtual double Area() = 0;
virtual void Display() = 0;
CQuadrilateral();
};
When a class is defined as abstract, you can implement any
of its properties if you want. If a method is not made pure virtual, you can
also define it. Here are examples:
public ref class CQuadrilateral abstract
{
private:
double bs;
public:
String ^ Name;
virtual property double Base
{
double get() { return bs; }
void set(double b)
{
if( b <= 0 )
bs = 0.00;
else
bs = b;
}
}
String ^ Description();
virtual double Perimeter() = 0;
virtual double Area() = 0;
CQuadrilateral();
};
CQuadrilateral::CQuadrilateral()
{
Name = L"Quadrilateral";
}
String ^ CQuadrilateral::Description()
{
return L"A quadrilateral is a geometric figure with four sides";
}
After creating an abstract class, even if you implement (some of)
its properties and methods, you cannot use the class. That is, you cannot declare a
variable or handle of the class. This is because the class is not complete.
Remember that it has at least one method that is not defined.
Deriving From an Abstract Class |
|
Because an abstract class is not complete, you cannot (yet)
use it. If you want to use it, you must derive a class from it. If you decide to
derive a class from an abstract one, you must implement every one of its pure
virtual methods in the new class. If you omit or forget defining a pure virtual method, you would
receive an error.
When declaring the pure virtual methods in the new class,
replace the = 0 expression with the override method. For the regular virtual
properties or methods, you must flag them with either the override or the
new keyword. Here is an example of a class that derives from an abstract
class:
public ref class CSquare : public CQuadrilateral
{
public:
CSquare();
virtual String ^ Description() new;
virtual double Perimeter() override;
virtual double Area() override;
virtual void Display() override;
};
Based on this, in the new class, define the pure virtual
method(s) as you want. After defining the new class, you can then instantiate it
and use it as necessary. Here is an example:
using namespace System;
public ref class CQuadrilateral abstract
{
private:
double bs;
protected:
String ^ Name;
public:
virtual property double Base
{
double get() { return bs; }
void set(double b)
{
if( b <= 0 )
bs = 0.00;
else
bs = b;
}
}
virtual String ^ Description();
virtual double Perimeter() = 0;
virtual double Area() = 0;
virtual void Display() = 0;
CQuadrilateral();
};
CQuadrilateral::CQuadrilateral()
{
Name = L"Quadrilateral";
}
String ^ CQuadrilateral::Description()
{
return L"A quadrilateral is a geometric figure with four sides";
}
public ref class CSquare : public CQuadrilateral
{
public:
CSquare();
virtual String ^ Description() new;
virtual double Perimeter() override;
virtual double Area() override;
virtual void Display() override;
};
CSquare::CSquare()
{
Name = L"Square";
}
String ^ CSquare::Description()
{
return L"A square is a quadrilateral with four equal sides";
}
double CSquare::Perimeter()
{
return 4 * Base;
}
double CSquare::Area()
{
return Base * Base;
}
void CSquare::Display()
{
Console::WriteLine(L" === Shape Properties ===");
Console::WriteLine(L"Name: {0}", Name);
Console::WriteLine(L"Description: {0}", CQuadrilateral::Description());
Console::WriteLine(L" {0}", Description());
Console::WriteLine(L"Side: {0}", Base);
Console::WriteLine(L"Perimeter: {0}", Perimeter());
Console::WriteLine(L"Area: {0}", Area());
}
int main()
{
CSquare ^ sqr = gcnew CSquare;
sqr->Base = 22.46;
sqr->Display();
Console::WriteLine();
return 0;
}
This would produce:
=== Shape Properties ===
Name: Square
Description: A square is a quadrilateral with four equal sides
Side: 22.46
Perimeter: 89.84
Area: 504.4516
Press any key to continue . . .
|