#455 – Define an Interface Based on Existing Members of a Class

You can use Visual Studio to define a new interface, based on existing members of a class.  This is also known as extracting an interface.

For example, suppose we have an existing Cow class that doesn’t currently implement any interfaces.  A Cow has properties like Name, MooLog and Motto, and methods like Moo, Dance and Burp.

We can create a new IMoo interface that consists of a Moo method and a MooLog property.  Since Cow already implements both of these members, we can extract the interface from the class.

Right-click on the Cow class name and select Refactor and then Extract Interface.

We then give the new interface a name (e.g. IMoo) and select the members of the existing class that should be part of the interface.

After clicking OK, Visual Studio generates the new interface.

Cow now inherits from IMoo.

#454 – Return an Interface as a Return Value from a Method

In addition to passing interface variables into a method as parameters, you can also pass an interface back as the return value of a method.

In the example below, we define a method that looks through an array of objects and returns the first object found that implements the IMoo interface.

        static IMoo FindAMooer(object[] candidates)
        {
            IMoo theMooer = null;

            foreach (object candidate in candidates)
            {
                if (candidate is IMoo)
                {
                    theMooer = (IMoo)candidate;
                    break;    // stop looking
                }
            }

            return theMooer;
        }

We can then pass in any array of objects to this method and the method will find the first one that can moo.

            Cow bessie = new Cow("Bessie", 4);
            Dog spike = new Dog("Spike", 5);

            IMoo mooer = FindAMooer(new object[] { spike, 42, "Jude", bessie });
            mooer.Moo();

#451 – Implement Interface Explicitly to Simplify How a Class Appears to Clients

When you implement an interface explicitly, clients of the class can only see members of the interface if they access the object through the interface.

Assume that you have a Cow class which implements both the IMoo and the IStrangeCowBehavior interfaces.

public class Cow : IMoo, IStrangeCowBehavior

Also assume that the Cow class implements IStrangeCowBehavior explicitly, but implements IMoo normally.  Now a variable of type Cow will have access to the IMoo methods, but not the IStrangeCowBehavior methods.

If client code wants access to the IStrangeCowBehavior methods in Cow, it will need to access them via a variable of type IStrangeCowBehavior.

We’ve simplified things because most code that works with Cow objects won’t need access to the Burp, Dance, and DriveTractor methods and won’t even see the methods.  But code that needs these methods can get at them by using the appropriate interface variable.

#450 – Interfaces Should Normally Start with the Letter ‘I’

Interface names will typically start with the letter I, to help distinguish them from classes.

    interface IMoo
    {
        void Moo();
    }

Starting the name of an interface with the letter I is only an agreed-upon convention.  The name of the interface could actually be any valid type name.  But starting the interface name with the letter I helps readers of your code realize that the type is an interface type, rather than a class.

#449 – You Can Pass an Interface Variable to a Method

You can include a parameter in a method whose type is an interface, allowing you to pass interface variables into the method.

For example, we can write a method that takes variable of type IMoo.

        private static void DoSomeMooing(IMoo mooer)
        {
            for (int i = 0; i < 3; i++)
                mooer.Moo();
        }

We can now pass into this method a reference to any object that implements IMoo.

We might pass in an interface variable:

            Cow bessie = new Cow("Bessie", 4);
            IMoo viaMoo = bessie;
            DoSomeMooing(viaMoo);


We could also just pass an instance of a Cow directly into the method.  It will be implicitly cast to a reference of type IMoo and so the DoSomeMooing method will have access only to the members of Cow that are part of IMoo.

            Cow bessie = new Cow("Bessie", 4);

            DoSomeMooing(bessie);

#448 – Use the is Operator to See if an Object Implements an Interface

We saw that we could use the as operator to cast an object to a variable of a particular interface type.  If the object’s type does not implement the interface, the as operator returns null.

            IMoo viaMoo = objSomething as IMoo;
            if (viaMoo != null)
                viaMoo.Moo();

You can also use the is operator to first check to see if an object’s class implements a particular interface.

        private static void MooIfYouCan(object mooCandidate)
        {
            IMoo viaMoo;
            if (mooCandidate is IMoo)
            {
                viaMoo = (IMoo)mooCandidate;
                viaMoo.Moo();
            }
        }

We can pass any object into this method and the IMoo.Moo method will be called only if the object implements the IMoo interface.

            Cow bossie = new Cow("Bossie", 12);
            object mooer = bossie;
            MooIfYouCan(mooer);

            mooer = new Dog("Bert", 5);
            MooIfYouCan(mooer);

#447 – Use as Operator to Get At an Object’s Interfaces

If a class implements an interface, you can assign a variable whose type is that class directly to a variable of the interface’s type.

            Cow bossie = new Cow("Bossie", 12);

            IMoo viaMoo = bossie;
            viaMoo.Moo();

However, there might be times when you have a variable of a more general type and the variable may or may not implement a particular interface. In these cases, you could use a dynamic cast to cast the object variable to the interface type.

            object objSomething = bossie;

            // Can't assign directly; need cast
            IMoo viaMoo = (IMoo)objSomething;
            viaMoo.Moo();

The only problem is that this cast will fail, throwing an InvalidCastException, if the object does not implement IMoo.  Instead, you can use the as operator, which essentially does the cast, but just returns null if the cast fails.

            IMoo viaMoo = objSomething as IMoo;
            if (viaMoo != null)
                viaMoo.Moo();

#446 – Deciding Between an Abstract Class and an Interface

An abstract class is a base class that may have some members not implemented in the base class, but only in the derived classes.  An interface is just a contract that a class can choose to fulfill–a list of member that it must implement if it implements the interface.  (Differences Between an Interface and an Abstract Class).

You’ll often use an abstract class when you use nouns to describe the is-a relationship between a base class and derived classes.  E.g. Person as an abstract base class and Man and Woman as derived classes.

By contrast, you’ll often use interfaces when you think about verbs that describe things that instances of a class can do.  E.g. IRun interface containing Run method, implemented by Man and Woman, but also Horse classes.

    public abstract class Person
    // ...

    public class Man : Person, IOperateTools, IDriveTractor

    // ...

    public class Woman : Person, IAskForDirections, ICollaborate

#445 – Differences Between an Interface and an Abstract Class

An interface provides a list of members, without an implementation, that a class can choose to implement.  This is similar to an abstract class, which may include abstract methods that have no implementation in the abstract class, but might also include an implementation for some of its members.

One difference is that an abstract class might include some members that are fully implemented in the abstract class.  Interfaces can’t include the implementations of any of their members.  An interface just describes what a class does, while an abstract class may define how something is done.

Another difference is that a class can inherit from multiple interfaces, but can inherit from at most one base class.  Abstract classes allow you to treat an object polymorphically, based on any of the classes in its inheritance chain.  Interfaces let you treat a class polymorphically, based on any of the interfaces it implements.

#444 – Interfaces Can Inherit from Other Interfaces

An interface can inherit from other interfaces.  A class implementing an interface must then implement all members of all interfaces in the inheritance chain.

For example, assume that we have an INameAndMotto interface with Name and Motto properties.

    interface INameAndMotto
    {
        string Name { get; set; }
        string Motto { get; set; }
    }

Now we can inherit this interface when we define the IMoo interface.

    interface IMoo : INameAndMotto
    {
        void Moo();
        List<string> MooLog { get; set; }
    }

Now if we specify that the Cow class inherits from IMoo, it must implement all methods in both IMoo and INameAndMotto.

    public class Cow : IMoo
    {
        public string Name { get; set; }
        public string Motto { get; set; }

        public void Moo()
        {
            Console.WriteLine("Moo");
        }

        public List<string> MooLog { get; set; }
    }