Alot of junior (maybe not only junior) developers has been asked in an interview "what is abstract class and how why do we need it if we have interfaces?". Let's try understand what is the abstract class, when it can be helpful and how it differs from an interface.
(Important note: in this article we will talk about classical abstract classes and interfaces. In some languages (like D or new java) some things can be different, so in the post I reference a C# language for examples.)
Differences
The main differences between abstract classes and interfaces are:- Abstract class can specify some implementation, which is common for all inherited classes
- Interface provides no implementation, only the contract.
When would you use abstract class.
Let's imagine that we are writing a program that deals with animal. All animals have something common. But as we know in nature we have different animales like Cates, Dogs etc, but there's no just Animal in a real world. It means that we also will want to forbid creating instances of an Animal class in our program.So we will end up with the next implementation of Animal:
public abstract Animal
{
public abstract string Name {get;}
public void Breathe()
{
Console.WriteLine(Name + " is breathing");
}
}
You can ask, why won't we just use a regular class and won't create instances of Animal class in our code? The reason for this is that the usually we write code in teams and it will mean that not all members of the team will know that you are not allowed to create an instance of Animal and at some point they will try to do this and this can lead to an unpredictable behavior of your program. Marking the class as abstract helps us to avoid such situations. If someone will try to create an instance of the Animal class - compiler will warn him that the class is abstract and you are not allowed to create instances of this class. So the next what this teammate will do is probably ask the team why can't we use an Animal class in this way, or will try to read some documentation on this topic.
And as you see we've created a new hierarchy of classes in our program now: all animaler will inherit base abstract class Animal and implement required abstract methods plus have some common methods that are already implemented in Animal class.
When would you use an interface
Interfaces defines a contract that the class that inherit interface must implement. Let's get back to the animals examples.When we create class Cat and inherit it from our base class Animal we say: Cat "is-a" Animal. Here we are creating a hierarchy.
But what if some animals can make noise but others not? We can't add it to a base class, because this behavior is not common for all animals. Instead we want to say that Cat "has-a" Noise.
C# lets you derive from one class only. However you can implement as many interfaces as you like - this is because an interface is just a contract which your class promises to implement.And instead of adding all possible thing that Animals can do to a base class we can instead find something common to all of them and add some uncommon behavior to implementations via interfaces. Which will help us to work with some types of animals in one way and with other in a different way. For example: we can make animals that "has-a" Noise to make some noise, and don't ask animals that can't do noise for this.
Examples
Let's make an example to see the differences:public abstract class Animal
{
public abstract string Name {get;}
public void Breathe()
{
Console.WriteLine(Name + " is breathing");
}
}
public interface ISay
{
void Say();
}
public class Cat : Animal, ISay
{
public override string Name {get {return "Cat";}}
public void Say()
{
Console.WriteLine("Meow");
}
}
public class Fox : Animal
{
public override string Name {get {return "Fox";}}
}
public class Program
{
public static void Main(string[] args)
{
var cat = new Cat();
var fox = new Fox();
// var animal = new Animal(); // Cannot create an instance of the abstract class
// All animals (cat and fox) can breathe.
MakeBreathe(cat);
MakeBreathe(fox);
// Output:
// Cat is breathing
// Fox is breathing
// But not all animals can say somthing (What does the fox say?)
SaySomething(cat);
SaySomething(fox);
// Output
// Meow
}
public static void MakeBreathe(Animal animal)
{
animal.Breathe();
}
public static void SaySomething<T>(T item) where T : class
{
if(item is ISay)
{
var speakable = item as ISay;
speakable.Say();
}
}
}
Conclusion
The key differences between abstract classes and interfaces are:- Abstract classes can have constants, members, method stubs (methods without a body) and defined methods, whereas interfaces can only have constants and methods stubs.
- Methods and members of an abstract class can be defined with any visibility, whereas all methods of an interface must be defined as
public
(they are defined public by default). - When inheriting an abstract class, a concrete child class must define the abstract methods, whereas an abstract class can extend another abstract class and abstract methods from the parent class don't have to be defined.
- Similarly, an interface extending another interface is not responsible for implementing methods from the parent interface. This is because interfaces cannot define any implementation.
- A child class can only extend a single class (abstract or concrete), whereas an interface can extend or a class can implement multiple other interfaces.
- A child class can define abstract methods with the same or less restrictive visibility, whereas a class implementing an interface must define the methods with the exact same visibility (public).
Comments
Post a Comment