I had learned sometime ago that abstract classes should always abstract their functions to an interface. So instead of having something like this –
abstract class a{
public int i;
public int foo();
}
class b : a{
public int foo(){return 42;}
}
we have something like this –
interface Ia{
public int foo();
}
abstract class a : Ia{
public int i;
}
class b : a{
public int foo(){return 42;}
}
From my perspective, this is better because of single responsibility, modularity, and maintainability. My colleague disagrees though, and states that there is no perceivable advantage to this and that it only adds to complexity. I tried to find some writing on this topic, but I cant remember the pattern name and my googling hasn’t turned anything up.
Is this pattern an actual thing? Was I right to abstract everything as much as I can, or is my colleague correct?
5
You both can be correct. In general, your approach falls under the purview of the Interface Segregation Principle and his falls under You Ain’t Going to Need It.
In my experience, it depends on what the interface is. Does it represent a concrete thing, or does it represent a trait of a variety of things?
If it represents a concrete thing, then just leave it as the abstract class. Making it an interface tempts people to multiply implement it, violating the Single Responsibility Principle since you’re then mixing your concrete thing and some other thing.
If it represents a trait that is held by a variety of things, then make it an interface. The interface better models the trait and lets a variety of things satisfy the interface.
Don’t make interfaces because you’re “supposed to”. Make interfaces because they properly model your problem domain.
1
Neither. Abstract classes and interfaces are not substitutable. If your class has a binary operation (that is, it inspects the private fields of another instance of its class), this simply can’t be done from an interface (because an interface hides its implementation). This is why, for example, you don’t see a union/merge operation in Java’s Set interface.
However, if you do need multiple implementations of a type then using interfaces is definitely the better approach when applicable. You can’t multiply-inherit classes, so as soon as you need something that has both foo
and bar
, you’re sunk. You can always implement multiple interfaces and reuse behavior with composition.
1