Now I will show you a problem that every developer faces, with a simple example. Let's say I have a Base class that has two methods, Print and Scan. Implementation of this class is shared cross subclasses that inherit from it.
public class Base
{
public void Print()
{
Console.WriteLine("I can print");
}
public void Scan()
{
Console.WriteLine("I can scan");
}
}
I have three printers, Machine A and B, C,
public class MachineA: Base
{
}
public class MachineB: Base
{
}
public class MachineC: Base
{
}
And in the main method, you can call,
static void Main(string[] args)
{
MachineA a = new MachineA();
a.Print();
a.Scan();
}
Now if I have another machine. let's say machine number four, but this machine does not support scan. How we can solve it?
We have two approaches we will discuss and will see the advantages and disadvantages of each approach.
In the first approach I will make the scan method virtual and override it and throw an exception in the Scan method. That this printer does not support scans like this.
public class Base
{
public void Print()
{
Console.WriteLine("I can print");
}
public virtual void Scan()
{
Console.WriteLine("I can scan");
}
}
public class MachineD : Base
{
public override void Scan()
{
throw new Exception("I not support scan");
}
}
And in the main method, you can call,
MachineD a = new MachineD();
a.Scan();
But some developers say this approach is antiPattern because it is not fair to make a client call function that throws an exception.
So it is good to make this function disappear.
So we will refactor the base class and make it contain a method that is shared with all classes.
public class Base
{
public void Print()
{
Console.WriteLine("Print");
}
}
And make another class that inherits from the base class call AdvancedPrinter that contains scan function.
public class AdvancedPrinter : Base
{
public void Scan()
{
Console.WriteLine("I can printer");
}
}
Now classes that support print and scan will inherit from AdvancedPrinter and class, not support will inherit from Base class.
public class MachineA : AdvancedPrinter
{
}
public class MachineD : Base
{
}
Now this code is cleaner.
static void Main(string[] args) {
MachineA a = new MachineA();
a.Print();
a.Scan();
MachineD d = new MachineD();
d.Print();
}