Interfaces - References


References to interfaces may be declared and used. That is, it is possible to create an interface variable. An interface variable can refer to any class that implements the interface. The version of any method that is called through the interface variable is that which is implemented by the deriving class. This process is similar to using a base class reference to access a virtual function in a derived class object (as described in the topic on virtual functions).

The next program uses the previous two programs to generate references to interfaces. The classes Seconds and Primes implement the interface ISequence. Both these classes are included in the program and both are accessed through an interface variable of the type ISequence.

// Interface3 - References to Interfaces

using System;

public interface ISequence
{
    uint Next();         // Return the next number
    void Reset();        // Reset to start
    void Start(uint s);  // Set starting point
}

class Seconds : ISequence
{
    uint start;
    uint current;

    public Seconds()
    {
        start = current = 0;
    }

    public uint Next()
    {
        current += 2;
        return current;
    }

    public void Reset()
    {
        current = start;
    }

    public void Start(uint s)
    {
        current = start = s;
    }
}

class Primes : ISequence
{
    uint start;
    uint current;

    public Primes()
    {
        start = current = 1;
    }

    public uint Next()
    {
        do
        {
            current++;
        } while (!IsPrime());

        return current;
    }

    public void Reset()
    {
        current = start;
    }

    public void Start(uint s)
    {
        current = start = s;
    }

    bool IsPrime()
    {
        if (current < 2) return false;

        bool is_prime = true;

        uint j = 2;
        while (j <= current / 2)
        {
            if (current % j == 0) { is_prime = false; break; }
            j++;
        }

        return is_prime;
    }
}

class Program
{
    static void Main()
    {
        ISequence A = new Seconds();  // Interface Reference
        ISequence B = new Primes();   // Interface Reference

        for (uint i = 0; i < 3; i++)
        {
            Console.WriteLine("Next Second: {0}", A.Next());
            Console.WriteLine("Next Prime:  {0}", B.Next());
        }

        
    }
}

In Main(), instances of Seconds and Primes are allocated via the new operator. The returned references are converted to references to the interface ISequence. Armed with these two reference variables, a number of entries in the sequence are printed. The resultant output is shown below.

Next Second: 2
Next Prime:  2
Next Second: 4
Next Prime:  3
Next Second: 6
Next Prime:  5

Clearly, an interface variable can be used only to access the components of the interface. Other components defined by the implementing class are inaccessible when the access is though the interface.