Interfaces and generics are two very different, yet complementary things:
- An interface defines a behavioral contract. A class implementing
IPizzamust fulfill this contract, i. e. offer aPreparemethod that meets the expectations. We don’t care if it’s a kind of pizza or not (for this we have classes). Btw, in real life projects, I never encountered anyIPizza: naming of interfaces often describe a behavioral trait:IPrintable,IDeliverable,ISortable,IComparable. The problem with tutorial examples is that they are often obersimplified and thus misleading. - Generics are using some kind of generalisation of a family of contracts or types to compose a more complex programming construct (e.g. class). Typically a collection of items that obey to dome sets of interfaces/types whose methods can be combined for making a more complex behavior. They do not substitute to interfaces. On contrary, they may use interfaces to define more complex containers.
By their essence, generics are compile-time type substitution, whereas interfaces offer a run-time polymorphism thanks to their defined contract.