Home

Interfaces

 

Introduction

In Lesson 6, we were introduced to inheritance as a way of laying a foundation that other classes could be based on. An example of such a class is:

public ref class CProperty
{
};

This type of class is vague. It's hardly usable to declare a variable or create a handle. Still, as we saw with abstract classes, you can create a class that serves only as a foundation for other classes. Like an abstract class, an interface is a class that is used only to create a skeleton class. The class cannot actually be instantiated but it can contain as much behavior as necessary.

Interface Creation

An interface is primarily created like a class but it adds the interface keyword on the left side of the class keyword. By tradition, the name of an interface starts with I. Here is an example:

interface class IGeometry
{
};

You can also include an assembly access level: Here is an example:

public interface class IGeometry
{
};

Like an abstract class, you cannot declare a variable of an interface. Still, when creating it, in its body, you can list the members that the child classes will inherit. The members can be properties or methods as we have used them in classes so far. Unlike an abstract class, you cannot define any method in the interface: you can only declare it. Also, unlike an abstract class, if the interface contains a property, you cannot define that property in the interface. You can only declare it. Here are examples of a property and a method in an interface:

public interface class IGeometry
{
	property String ^ Name;
	void Display();
};

Practical LearningPractical Learning: Introducing Interfaces

  1. Create new CLR Empty Project named RealEstate11
  2. To create a new file, on the main menu, click Project -> Add New Item...
  3. In the Templates list, click Header File (.h)
  4. Set its name to Property and press Enter
  5. In the empty file, type:
     
    interface class IProperty
    {
        property long PropertyNumber;
        void ShowProperty();
    };
  6. Save the file

Inheriting From an Interface

After creating an interface, you can inherit a class from it. Besides, like an abstract class, you cannot use an interface without creating a new class from it that you would eventually use to declare a variable. You primarily inherit from an interface the same way you would create a child class. Here is an example:

public interface class IGeometry
{
	property String ^ Name;
	void Display();
};

public ref class CRound : public IGeometry
{
};

One of the fundamental differences between an abstract class and an interface is that the former can contain member variables and defined methods. The later cannot contain member variables but properties and declared methods. Another difference between both is that you cannot define a property or a method in an interface class, which you can do in an abstract class. Because of the definition of an interface, after basing a class on it, since none of its members would have been defined, you must define each one (all) of them in a class derived from an interface. Here is an example:

using namespace System;

public interface class IGeometry
{
	property String ^ Name;
	void Display();
};

public ref class CRound : public IGeometry
{
private:
	String ^ _name;

public:
    CRound();
    CRound(String ^ name);

    property String ^ Name
    {
	virtual String ^ get() { return _name; }
	virtual void set(String ^ value) { _name = value; }
    }
	
    virtual void Display();
};

CRound::CRound()
{
    _name = L"Unknown";
}

CRound::CRound(String ^ name)
{
    _name = name;
}

void CRound::Display()
{
    Console::WriteLine(L"Name: {0}", Name);
}

As mentioned earlier, after deriving a class from an interface, you can then declare a variable from it. Here is an example:

int main()
{
    CRound ^ rnd = gcnew CRound;
    rnd->Display();
    Console::WriteLine();

    rnd->Name = L"General Round Shape";
    rnd->Display();
    Console::WriteLine();

    return 0;
}

This would produce:

Name: Unknown

Name: General Round Shape

Press any key to continue . . .

As seen in previous lessons, after creating a non-sealed class, you can inherit a class from it. This is one of the best features of C++ and C++/CLI. For example, you can derive a class from another class that itself was derived from an interface. When deriving this new class, you can add new members that were not declared in the interface. You can also override the interface's member(s) or new them. Here is an example:

using namespace System;

public interface class IGeometry
{
	property String ^ Name;
	void Display();
};

public ref class CRound : public IGeometry
{
private:
	String ^ _name;

public:
    CRound();
    CRound(String ^ name);

    property String ^ Name
    {
	virtual String ^ get() { return _name; }
	virtual void set(String ^ value) { _name = value; }
    }
	
	virtual void Display();
};

CRound::CRound()
{
	_name = L"Unknown";
}

CRound::CRound(String ^ name)
{
    _name = name;
}

void CRound::Display()
{
    Console::WriteLine(L"Name: {0}", Name);
}

public ref class CCircle : public CRound
{
private:
    double rad;

public:
    property double Radius
    {
	double get() { return rad; }
        void set(double value)
	{
		rad = (value <= 0) ? 0.00 : value;
	}
    }

    virtual double Area();
    virtual void Display() new;
};

double CCircle::Area()
{
    return Radius * Radius * 3.14159;
}

void CCircle::Display()
{
    Console::WriteLine(L"Figure: {0}", Name);
    Console::WriteLine(L"Radius: {0}", Radius);
    Console::WriteLine(L"Area:   {0}", Area());
}

int main()
{
    CCircle ^ circ = gcnew CCircle;
    circ->Name = L"Circle";
    circ->Radius = 36.82;
    circ->Display();

    Console::WriteLine();
    return 0;
}

This would produce:

Figure: Circle
Radius: 36.82
Area:   4259.092518716

Press any key to continue . . .

Practical LearningPractical Learning: Using an Interface

  1. Change the contents of the Property.h file as follows:
     
    using namespace System;
    
    public enum class PropertyCondition
    {
        Excellent,
        Good,
        NeedsRepair,
        Bad,
        Unspecified
    };
    
    interface class IProperty
    {
        property long PropertyNumber;
        property int Bedrooms;
        property float Bathrooms;
        property PropertyCondition Condition;
        property double Value;
    
        void ShowProperty();
    };
  2. To create a new file, on the main menu, click Project -> Add New Item...
  3. In the Templates list, make sure that Header File (.h) is selected.
    Set its name to House and press Enter
  4. In the empty file, type:
     
    public ref class CHouse : public IProperty
    {
    public:
        long   nbr;
        int    beds;
        float  baths;
        PropertyCondition cond;
        double val;
    
    public:
        property long PropertyNumber
        {
    	virtual long get() { return nbr; }
    	virtual void set(long n) { nbr = n; }
        }
    
        property int Bedrooms
        {
    	virtual int get() { return beds; }
    	virtual void set(int b) { beds = b; }
        }
    
        property float Bathrooms
        {
    	virtual float get() { return baths; }
    	virtual void set(float b) { baths = b; }
        }
    	
        property PropertyCondition Condition
        {
    	virtual PropertyCondition get() { return cond; }
    	virtual void set(PropertyCondition c) { cond = c; }
        }
    
        property double Value
        {
    	virtual double get() { return val; }
    	virtual void set(double v) { val = v; }
        }
    
        virtual void ShowProperty()
        {
    	Console::WriteLine(L"=//= Real Estate - Catalog =//=");
    	Console::WriteLine(L"-- Property Type: Townhouse --");
    	Console::WriteLine(L"Property #: {0}", this->PropertyNumber);
    	Console::Write(L"Condition:      ");
    	Console::WriteLine(Condition);
    	Console::WriteLine(L"Bedrooms:   {0}", this->Bedrooms);
    	Console::WriteLine(L"Bathrooms:  {0}", this->Bathrooms);
    	Console::WriteLine(L"Value:      {0:C}", this->Value);
        }
    };
  5. To create a new file, on the main menu, click Project -> Add New Item...
  6. In the Templates list, make sure that Header File (.h) is selected.
    Set its name to House and press Enter
  7. In the empty file, type:
     
    #include "Property"
    
    public ref class CHouse : public IProperty
    {
    public:
        long   nbr;
        int    beds;
        float  baths;
        PropertyCondition cond;
        double val;
    
    public:
        property long PropertyNumber
        {
    	virtual long get() { return nbr; }
    	virtual void set(long n) { nbr = n; }
        }
    
        property int Bedrooms
        {
    	virtual int get() { return beds; }
    	virtual void set(int b) { beds = b; }
        }
    
        property float Bathrooms
        {
    	virtual float get() { return baths; }
    	virtual void set(float b) { baths = b; }
        }
    	
        property PropertyCondition Condition
        {
    	virtual PropertyCondition get() { return cond; }
    	virtual void set(PropertyCondition c) { cond = c; }
        }
    
        property double Value
        {
    	virtual double get() { return val; }
    	virtual void set(double v) { val = v; }
        }
    
        virtual void ShowProperty();
    };
  8. To create a new file, on the main menu, click Project -> Add New Item...
  9. In the Templates list, click C++ File (.cpp) is selected
  10. Set its name to House and press Enter
  11. In the empty file, type:
     
    #include "House"
    
    void CHouse ::ShowProperty()
    {
        Console::WriteLine(L"=//= Real Estate - Catalog =//=");
        Console::WriteLine(L"-- Property Type: Townhouse --");
        Console::WriteLine(L"Property #: {0}", this->PropertyNumber);
        Console::Write(L"Condition:      ");
        Console::WriteLine(Condition);
        Console::WriteLine(L"Bedrooms:   {0}", this->Bedrooms);
        Console::WriteLine(L"Bathrooms:  {0}", this->Bathrooms);
        Console::WriteLine(L"Value:      {0:C}", this->Value);
    }
  12. To create a new file, on the main menu, click Project -> Add New Item...
  13. In the Templates list, make sure that C++ File (.cpp) is selected.
    Set its name to Exercise and press Enter
  14. In the empty file, type:
     
    #include "House.h" 
    
    int main()
    {
    	CSingleFamily ^house = gcnew CSingleFamily;
    
    	house->PropertyNumber = 307473;
    	house->Condition = PropertyCondition::Excellent;
    	house->Stories   = 3;
    	house->Bedrooms  = 5;
    	house->Bathrooms = 3.5F;
    	house->YearBuilt = 2002;
    	house->Value     = 708950;
    	house->ShowProperty();
    
    	Console::WriteLine();
    	return 0;
    }
  15. Execute the application to see the result
  16. Close the DOS window

Deriving From a Class and an Interface

As we have seen so far, in C++, you can inherit from:

Multiple inheritance consists of inheriting a class from more than two other classes. This is possible in C++ because the language allows it. In C++/CLI, you cannot inherit from more than two classes. Instead, you can inherit from:

  • One class and one interface
  • One class and more than one interface
 

Previous Copyright © 2006 FunctionX, Inc. Next