Now with C# 8, we can provide implementation into the interfaces too then what is the point of the Abstract class? what is the difference?
Here is my analysis.
Here is my analysis.
Concepts
- An interface is a contract that tells the client the class has an implementation of the required methods that means ILogger tells the client ConsoleLogger has implemented all the methods. But derived class is the extension of the Abstract class like ConsoleLogger extending the BaseLogger.
- With the parent class, the derived class has to have a "is a" relation while it's not required with the interfaces.
Programmatically
Well, on the surface after the default implementation functionality abstract class and interface seem the same but they are a lot different if you look closely.
- The default implementation in interfaces works when no implementation is provided but with an abstract class, functionality could be extended calling super method, encapsulated using private methods, and also overridden like interfaces too.
- Multiple interfaces can be implemented for a single class but only one parent class can exist.
But why default implementations anyway?
- It helps extend an interface which is been implemented by lots of classes already.
- Interface function could be reused inside interface, then no need to copy same code in every implementation. Suppose ILogger has methods LogError and LogWrite. LogError under the hood is using LogWrite anyway to write anyway then why provide the same implementation everywhere for LogError?
Let's tackle elephant in the room, the diamond problem. if class A is the parent of class B and C both have the same child D then which implementation will be called when using an object of class D? That is one of the problems multiple inheritances doesn't exist in modern language and it is a pitfall developers tend to fall into if program is not designed carefully.
But here are the rules C# has implemented to keep developers safe.
- Default implementation belongs to interface not class. That means
public interface IA
{
public void Write() => Console.WriteLine("IA Written");
}
public interface IB
{
public void Write() => Console.WriteLine("IB Written");
}
public interface IC : IA, IB
{
}
public class C : IC
{
}
class Program
{
static void Main(string[] args)
{
IA c = new C();
c.Write(); // prints IA Written
IB d = new C();
d.Write(); // prints IB Written
IC e = new C();
e.Write(); // compile time exception
Console.ReadKey();
C f = new C();
f.Write(); // compile time exception
}
}