Some language features (like lambdas as an example) make you say, "Wow, now that is cool" and make you want to run out and use them. Interfaces have always made me say, "OK, yeah, so what's the point?" I'm not alone, there are all kinds of online questions that ask, "What am I missing about interfaces?".
I am going to take the approach of writing some code that uses interfaces and see if getting my hands dirty turns on the light bulb.
And here is working code:using System; namespace Example { public interface Pizza { void Bake(); } public class P_pizza : Pizza { public void Bake() { Console.WriteLine ( "Baking a pepperoni pizza" ); } } public class M_pizza : Pizza { public void Bake() { Console.WriteLine ( "Baking a mushroom pizza" ); } } public class ThemPizzas { private static ListSo, we declare a "Pizza" interface. We indicate that to participate in this interface, you must provide a "Bake" method. So any class with a Bake method (with no arguments and returning void) is eligible.pizzas = new List (); public static void setup () { pizzas = new List (); pizzas.Add ( new Example.P_pizza () ); pizzas.Add ( new Example.M_pizza () ); } public static void make () { foreach ( Pizza p in pizzas ) p.Bake (); } } } namespace HogHeaven { public class Program { public static void Main(string[] args) { Example.ThemPizzas.setup (); Example.ThemPizzas.make (); Console.WriteLine ( "All done" ); } } } // THE END
Next we declare two classes. They "inherit from" the Pizza interface -- if you want to use those words for this syntax (which ain't right the right way to talk about it, but it is the same syntax used to indicate inheritance, so we will go with it.) These classes could provide any sort of other fields and methods, but as long as they have a "Bake()" method, we are good.
Now I have a thrown together class "ThemPizzas" that is sort of a unit test for all of this. The most interesting thing (to my mind) is that we can use the "Pizza" interface name as a type in the List generic. As it turns out in C#, pretty much everything is a type. Classes, Interfaces, Structs, and so on. Hence this should not be surprising. In other object oriented languages, the usual slogan is that everything is an object. Maybe a type is a sort of object. Probably, Maybe -- it only matters if we want to split hairs and keep the computer language nomenclature nazis off of our back.
Because our two pizza classes implement the "Pizza" interface, we can add them to the "pizzas" list. And finally, what you could consider the most useful outcome of all this, we can loop through the "pizzas" list and call the Bake method for each item. Each object knows how to take care of itself and so we see the output:
Baking a pepperoni pizza Baking a mushroom pizza All doneThis is pretty much a conventional example of the use of Interfaces that you see kicked around in books and on forums. Many people with even a basic understanding of object oriented programming will raise an objection. They will say, "You could have done this with a base class and inheritance and skipped this interface business." They are correct.
Another final note. Purists may get worked up over the use of List, scold you, and tell you that you should use IList instead. They may have good reasons, but at this point I cannot say. What I can say is that a plain old List "just works". Until I know what they are worked up about, I will continue to use List.
If you use List instead of IList and somebody comes and raps your knuckes, don't come crying to me. BUT -- IList is an interface and List is a class, so you cannot just replace List with IList in the above code. What is actually going on is that List is a specific concrete implementation of the IList interface. Read the discussion in the link above -- which goes on to say there are some unfortunate design decisions involving IList.
Tom's Computer Info / tom@mmto.org