Книга: C# 2008 Programmer
Explicit Interface Members Implementation
Explicit Interface Members Implementation
A class can implement one or more interfaces. To implement a member in an interface, you simply need to match the member name and its signature with the one defined in the interface. However, there are times when two interfaces may have the same member name and signature. Here's an example:
public interface IFileLogging {
void LogError(string str);
}
public interface IConsoleLogging {
void LogError(string str);
}
In this example, both IFileLogging
and IConsoleLogging
have the same LogError()
method. Suppose that you have a class named Calculation
that implements both interfaces:
public class Calculation : IFileLogging, IConsoleLogging {}
The implementation of the LogError()
method may look like this:
public class Calculation : IFileLogging, IConsoleLogging {
//---common to both interfaces---
public void LogError(string str) {
Console.WriteLine(str);
}
}
In this case, the LogError()
method implementation will be common to both interfaces and you can invoke it via an instance of the Calculation
class:
Calculation c = new Calculation();
//---prints out: Some error message here---
c.LogError("Some error message here");
In some cases, you need to differentiate between the two methods in the two interfaces. For example, the LogError()
method in the IFileLogging
interface may write the error message into a text file, while the LogError()
method in the IConsoleLogging
interface may write the error message into the console window. In that case, you must explicitly implement the LogError()
method in each of the two interfaces. Here's how:
public class Calculation : IFileLogging, IConsoleLogging {
//---common to both interfaces---
public void LogError(string str) {
Console.WriteLine(str);
}
//---only available to the IFileLogging interface---
void IFileLogging.LogError(string str) {
Console.WriteLine("In IFileLogging: " + str);
}
//---only available to the IConsoleLogging interface---
void IConsoleLogging.LogError(string str) {
Console.WriteLine("In IConsoleLogging: " + str);
}
}
This example has three implementations of the LogError()
method:
? One common to both interfaces that can be accessed via an instance of the Calculation
class.
? One specific to the IFileLogging
interface that can be accessed only via an instance of the IFileLogging
interface.
? One specific to the IConsoleLogging
interface that can be accessed only via an instance of the IConsoleLogging
interface.
You cannot use the public
access modifier on the explicit interface methods' implementation.
To invoke these implementations of the LogError()
method, use the following statements:
//---create an instance of Calculation---
Calculation c = new Calculation();
//---prints out: Some error message here---
c.LogError("Some error message here");
//---create an instance of IFileLogging---
IFileLogging f = c;
//---prints out: In IFileLogging: Some error message here---
f.LogError("Some error message here");
//---create an instance of IConsoleLogging---
IConsoleLogging l = c;
//---prints out: In IConsoleLogging: Some error message here---
l.LogError("Some error message here");
Another use of explicit interface member implementation occurs when two interfaces have the same method name but different signatures. For example:
public interface IFileLogging {
void LogError(string str);
}
public interface IConsoleLogging {
void LogError();
}
Here, the LogError()
method in the IFileLogging
interface has a string input parameter, while there is no parameter in the IConsoleLogging
interface. When you now implement the two interfaces, you can provide two overloaded LogError()
methods, together with an implementation specific to each interface as illustrated here:
public class Calculation : IFileLogging, IConsoleLogging {
//---common to both interfaces---
public void LogError(string str) {
Console.WriteLine("In LogError(str): " + str);
}
public void LogError() {
Console.WriteLine("In LogError()");
}
//---only available to the IFileLogging interface---
void IFileLogging.LogError(string str) {
Console.WriteLine("In IFileLogging: " + str);
}
//---only available to the IConsoleLogging interface---
void IConsoleLogging.LogError() {
Console.WriteLine("In IConsoleLogging");
}
}
As you can see , the first two LogError()
methods are overloaded
and are common to both interfaces. This means that you can access them via an instance of the Calculation
class. The next two implementations are specific to the IFileLogging
and IConsoleLogging interfaces and can be accessed only via an instance of each interface:
//---create an instance of Calculation---
Calculation c = new Calculation();
//---prints out: In LogError()---
c.LogError();
//---prints out: In LogError(str)---
c.LogError("Some error message here");
//---create an instance of IFileLogging---
IFileLogging f = c;
//---prints out: In IFileLogging: Some error message here---
f.LogError("Some error message here");
//---create an instance of IConsoleLogging---
IConsoleLogging l = c;
//---prints out: In IConsoleLogging---
l.LogError();
Abstract Classes versus Interfaces
An abstract class defines the members and optionally provides the implementations of each member. Members that are not implemented in the abstract class must be implemented by classes that inherit from it.
An interface, on the other hand, defines the signatures of members but does not provide any implementation. All the implementations must be provided by classes that implement it.
So which one should you use? There are no hard-and-fast rules, but here are a couple of points to note:
? You can add additional members to classes as and when needed. In contrast, once an interface is defined (and implemented by classes), adding additional members will break existing code.
? Classes support only single-inheritance but can implement multiple interfaces. So if you need to define multiple contracts (rules) for a type, it is always better to use an interface.
- Implementation Inheritance
- Implementation ID
- Chapter 15. Graphical User Interfaces for Iptables
- Explicit matches
- Displaying Interface Statistics
- QueryInterface и IUnknown
- 5.1.2. The Directory Server Interface
- Command-Line Network Interface Configuration
- Laying the Foundation: The localhost Interface
- Checking for the Availability of the Loopback Interface
- Configuring the Loopback Interface Manually
- Graphic Interface Configuration of Apache