In object-oriented programming, C# interfaces are a potent tool that specify a contract for behaviour that structs or classes can implement.
This is a thorough description of interfaces that includes examples, their features, and their purpose:
What is an Interface in C#?
A completely unimplemented class in C# that is used to declare a collection of an object’s operations is called an interface. Since you may only define abstract methods using it, it is regarded as a pure abstract class. A syntactical contract’s “what” is essentially defined by an interface, and its “how” is defined by the classes that implement it.
Key Characteristics of Interfaces
Declarations Only: Only method, property, indexer, and event declarations are permitted in an interface. Implementations (method bodies, data fields, or constructors) are not allowed.
Implicitly Public and Abstract: An interface’s members are all by default public and abstract. Interface members cannot be designated as private or protected. Any access modifier that is specified for interface members will cause a compilation error.
Cannot be Instantiated: An instance of an object cannot be created straight from an interface. Nonetheless, a reference variable for an interface can be made to hold a reference to a subclass object.
No Fields or Constructors: Interfaces are not allowed to have constructors or data fields (instance variables).
Cannot be Sealed: You can’t declare an interface sealed.
Inheritance: An interface inherits all of its base interface members and may inherit from one or more other interfaces. On the other hand, an interface cannot inherit from any other class or from an abstract class.
Comparison with Abstract Classes
There are some significant distinctions between interfaces and abstract classes, even though both cannot be instantiated and need subclasses to implement their abstract methods:
Implementation: Both concrete (non-abstract) and abstract methods can be defined by an abstract class that is partially implemented. Only abstract methods are defined in an interface that is completely unimplemented.
Data Fields: There can be data fields in an abstract class. Data fields are not allowed on an interface.
Accessibility: Members of an abstract class can have their accessibility modifiers altered from the default private. Members of an interface cannot be altered and are set to public by default.
Inheritance: Multiple interfaces can be implemented by a class, but it can only inherit from one base class, including abstract classes. An interface or another abstract class may be the inheritance source for an abstract class.
Why Use Interfaces?
Interfaces are important in C# programming for a number of reasons:
Defining Contracts: Interfaces serve as a “contract” of functionality, outlining a set of functions that must be provided by any implementing class. This guarantees that certain behaviours will be exposed by classes that follow an interface.
Achieving Abstraction: Abstraction is made possible by interfaces, which let you operate with abstract data structures or components according to their specified functions and behaviours without having to understand the specifics of the underlying implementation. Code becomes more resilient to changes as a result.
Enabling Polymorphism: Polymorphism is extended beyond conventional inheritance hierarchies through interfaces. It is possible to regard any class that implements an interface as that interface type, which enables consistent interaction with a variety of objects that have a common contract, even if they are not related by class inheritance.
Supporting Multiple Inheritance: Interfaces enable a class to accomplish multiple inheritance of behaviour by implementing several interfaces, even if C# classes do not natively support it. The intricacy and possible conflicts that arise from inheriting implementation from several base classes are eliminated in this way.
Loose Coupling: Programming against interfaces encourages loose connection between components instead of actual classes. When a component’s implementation changes, other components won’t be impacted as long as the interface (contract) stays the same.
Extensibility: Interfaces facilitate program extension by enabling the addition of new classes that implement pre-existing interfaces without necessitating modifications to the existing code that communicates with those interfaces.
Design Patterns: In order to facilitate adaptable and reusable software structures, interfaces are actively used in many popular design patterns, such the Adapter pattern.
Declaring and Implementing Interfaces
To declare an interface, use the interface keyword.
Syntax for Declaring an Interface:
public interface IExampleInterface
{
// Method declaration (implicitly public and abstract)
void DoSomething();
// Property declaration (implicitly public and abstract with accessors)
int MyProperty { get; set; }
// Event declaration (implicitly public and abstract)
event EventHandler MyEvent;
// Indexer declaration (implicitly public and abstract)
string this[int index] { get; }
}
Implementing an Interface: A class or struct “implements” an interface by putting the name of the interface after its own name, with a colon (:) between them. The base class name must be before the interface names if a class implements interfaces and inherits from a base class. All members listed in the interface description must have an implementation provided by the class or struct that implements the interface, unless the implementing class is designated abstract. The implemented members need to be non-static, public, and share the interface member’s name and signature.
Example of Interface Implementation
Examine an interface called INoiseMaker that has a MakeNoise() function defined.
using System; // Make sure to include this for Console.WriteLine
public interface INoiseMaker // Declaring the interface
{
string MakeNoise(); // Method signature
}
public class Cat : INoiseMaker // Implementing the interface
{
public string Name { get; set; } // Property as part of the class, not the interface itself
public Cat()
{
Name = "Cat";
}
public string MakeNoise() // Implementation of the interface method
{
return "Nyan";
}
}
public class Dog : INoiseMaker // Another class implementing the same interface
{
public string MakeNoise() // Implementation specific to Dog
{
return "Woof";
}
}
// Usage demonstrating polymorphism
public static class Program // Main method must be inside a class
{
public static void Main()
{
INoiseMaker cat = new Cat();
INoiseMaker dog = new Dog();
Console.WriteLine(cat.MakeNoise());
Console.WriteLine(dog.MakeNoise());
}
}
Output
Nyan
Woof
Explicit Interface Implementation
When there is a naming collision (for example, a property and a method with the same name across distinct interfaces) or when a class implements multiple interfaces that describe members with the same signature but require different implementations, explicit interface implementation is required.
Explicitly implemented members can only be accessed via the interface instance; they cannot be invoked directly from the class instance.
Example of Explicit Interface Implementation: Examine two interfaces that define the Drive() method: IChauffeur and IGolfPlayer.
using System;
interface IChauffeur
{
string Drive();
}
interface IGolfPlayer
{
string Drive();
}
class GolfingChauffeur : IChauffeur, IGolfPlayer // Class implementing both interfaces
{
// Public implementation, used by default if not explicitly specified
public string Drive()
{
return "Vroom!"; // Chauffeur's driving style
}
// Explicit implementation for IGolfPlayer
string IGolfPlayer.Drive()
{
return "Took a swing..."; // Golfer's "drive" style
}
}
// Main method must be inside a class
public static class Program
{
// Usage of explicit interface members
public static void Main()
{
GolfingChauffeur obj = new GolfingChauffeur();
// Calling the public (implicit) implementation
Console.WriteLine(obj.Drive()); // Outputs: Vroom!
// Accessing implementations via interface casting
IChauffeur chauffeur = obj;
IGolfPlayer golfer = obj;
Console.WriteLine(chauffeur.Drive()); // Outputs: Vroom! (calls the public implementation)
Console.WriteLine(golfer.Drive()); // Outputs: Took a swing... (calls the explicit IGolfPlayer implementation)
// obj.IGolfPlayer.Drive(); // This would be a compile-time error! Explicit members can't be called directly.
}
}
Output
Vroom!
Vroom!
Took a swing...
Common .NET Interfaces and Related Concepts
Interfaces are the foundation of many essential.NET Framework features:
Collections: Interfaces such as IEnumerable, IEnumerable, IList, and IDictionary specify common methods for working with data collections.
Comparisons: Object comparison techniques are defined by IComparable and IComparable.
Resource Management: IDisposable plays a key role in managing unmanaged resources by making sure the Dispose() function, which is frequently used in conjunction with the using statement, is used to release them appropriately.
Events: In C#, classes must implement events that are declared by interfaces. Events are based on delegates.
Extension Methods: Without changing the interfaces’ original design or the classes that implement them, new functionality can be “added” to existing interfaces by defining extension methods.
Structs and Interfaces: Unlike classes, structs can implement one or more interfaces but are unable to inherit from other structs or classes.
Design Patterns: In order to apply different design patterns, like the Adapter pattern, interfaces are essential.
In conclusion, interfaces play a crucial role in C# and object-oriented design by offering crucial features for abstraction, polymorphism, and the creation of adaptable, expandable, and maintainable software systems.