using System; namespace Example { public class Pizza { protected int size; // void Bake(); public Pizza ( int arg ) { size = arg; } public virtual void Bake() { Console.WriteLine ( "Baking an ordinary pizza" ); } } public class P_pizza : Pizza { public P_pizza ( int arg ) : base ( arg ) {} public override void Bake() { Console.WriteLine ( $"Baking a {size} inch pepperoni pizza" ); } } public class M_pizza : Pizza { public M_pizza ( int arg ) : base ( arg ) {} public override void Bake() { Console.WriteLine ( $"Baking a {size} inch mushroom pizza" ); } } public class ThemPizzas { private static ListThe only new code is in the P_pizza, M_pizza classes -- and we have added a base "Pizza" class in lieu of the Pizza interface in the last section. You could call it a matter of taste whether using an Interface is better, or whether this is better. Beginning OO programmers will learn towards familiar concepts like inheritance. More experienced programmers may find an interface a cleaner way to accomplish what we have done here.pizzas = new List (); public static void setup () { pizzas = new List (); pizzas.Add ( new Example.P_pizza ( 8 ) ); pizzas.Add ( new Example.M_pizza ( 8 ) ); } 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
I have added a new feature, namely a constructor in the base class that sets the pizza size. This ends up showcasing some unexpected syntax to cause the derived classes to call the base class constructor. Also I found that I had to use the "protected" word on "size" to allow the child classes permission to access this field in the parrent. The other interesting thing is the need to declare the Bake method "virtual" in the base class, then explicitly state "override" in the child classes. I suppose having the C# language force you to be deliberate about this avoids an override happening by accident.o
These things are all regular features of classes and inheritance. There is nothing exciting or surprising here that use of a interface would make simpler or clearer. Note that the "ThemPizzas" and "Program" class are exactly the same as for the code we wrote using "interface". This surprises me -- I expected that there would be some special hanky-panky required to set up a list with different object classes, then to invoke the Bake() method, but it all "just works".
So, have we proved that "interface" is useless and stupid? Sort of. It is at least unnecessary in this scenario. What we have not explored yet is multiple inheritance. C# does not support multiple inheritance from classes. But a class can implement multiple interfaces, and this yields what most people are itching for when they start an uproar about C# not supporting multiple inheritance. So "interface" is an alternate style for some programming situations (like the pizza example we have been playing with). It is also possible for a class to implement multiple interfaces and this does offer something unique.
However, there is a whole different view on this business, and that is the subject of the next section.
Tom's Computer Info / [email protected]