23

If you have a class which inherits from two distinct classes, does not this mean that your subclass automatically does (at least) 2 things, one from each superclass?

I believe there is no difference if you have multiple interface inheritance.

To be clear, I believe that if subclassing multiple classes violates SRP, then implementing multiple (non-marker or basic interface (e.g. Comparable)) interfaces violates SRP too.

9
  • Just to be clear, you also believe implementing multiple interfaces violates the SRP?
    – user7043
    Aug 7, 2012 at 16:44
  • I believe that if subclassing multiple classes violates SRP, then implementing multiple (non-marker) interfaces violates SRP too.
    – Random42
    Aug 7, 2012 at 17:56
  • 1
    @NickC: I have not said my opinion (you should have read the above comment); I will edit the question to make it more clear.
    – Random42
    Aug 8, 2012 at 6:00
  • 1
    @NickC I do not have an opinion, that's why I asked. I only said that the two are related (interface inheritance and class inheritance); if it violates for class inheritance then it violates for interface inheritance too, if it doesn't for one then neither does it violate for the other. And I do not care about the up vote...
    – Random42
    Aug 8, 2012 at 11:32
  • 3
    The single responsibility principle does not say that a class cannot do two or more things. A class can do as many things as you want as long as they are related to the same business requirement.
    – JacquesB
    Nov 19, 2021 at 19:55

7 Answers 7

20

In a very narrow sense, the answer is "Yes": assuming that your base classes or interfaces are designed for a single purpose, inheriting both of them does create a class with multiple responsibilities. However, whether or not it is "a bad thing" depends on the nature of the classes or interfaces that you are inheriting.

You can partition your classes and interfaces into two major groups - the ones addressing the essential complexity of your system, and the ones addressing its accidental complexity. If you inherit from more than one "essential complexity" classes, it is bad; if you inherit from one "essential" and one or more "accidental" classes, it is OK.

For example, in a billing system you could have classes for representing invoices and billing cycles (they address the essential complexity) and classes for persisting objects (they address the accidental complexity). If you inherit like this

class BillingCycleInvoice : public BillingCycle, public Invoice {
};

it is bad: your BillingCycleInvoice has a mixed responsibility as it relates to the essential complexity of the system.

On the other hand, if you inherit like this

class PersistentInvoice : public Invoice, public PersistentObject {
};

your class is OK: technically, it services two concerns at once, but since only one of them is essential, you can write off inheriting the accidental one as the "cost of doing business".

2
  • 5
    Your second example is very similar to what would be a cross-cutting concern in aspect-oriented programming. This is saying that your objects sometimes need to do things (like logging, access control tests, or persisting) that aren't their core focus, and that you can do that with multiple inheritance. That's an appropriate use of the tool.
    – user4051
    Aug 8, 2012 at 8:08
  • The Simplest is If implementing a new interface requires to complete the class functionality then its not. But if its adding new responsibility Implement interface with some other class then inject as dependency will never violate SRP Nov 16, 2017 at 7:17
11

The SRP is a guideline to avoid god-classes, which are bad, but it also can be taken too literally and a project starts balloon with tons of classes that can't really do anything without a handful being combined. Multiple inheritance/multiple interfaces can be a sign a class is getting too big, but it could also be a sign that your focus is far too granular for the task at hand and your solution is over-engineered, or it could simply be a perfectly valid use case for multiple inheritance and your worries are unfounded.

Software design is as much art as science, its a balancing act of many competing interests. We have rules to help avoid things we know are to far in one direction that cause problems, but those rules can just as easily take us to a place that is just as bad or worse than what we were trying to avoid in the first place.

4

Somewhat. Let's focus on the main principle for SRP:

A class should only have one reason to change.

Multiple inheritance doesn't force this, but tends to lead to it. If the class overrides or implements its base classes, that tends to be more reasons for it to change. In this way, interface multiple inheritance tends to be more troublesome than class inheritance. If two classes are inherited but not overridden, then the reasons to change exist in the base classes not the new class.

The places where multiple inheritance does not violate SRP is when all but one of the base types aren't something that the class is implementing, but act as a trait that the class happens to have. Consider IDisposable in C#. Things that are disposable don't have two responsibilities, the interface just acts as a view into classes that share the trait but have decidedly different responsibilities.

4

Not at all. In Java, you can have an interface that represents some sort of domain object--a Foo, for example. It may need to be compared to other Foo objects, and so it implements Comparable (with the comparison logic externalized in a Comparator class); it may be that this object also needs to be Serializable, so that it can be transported across the network; and it may need to be Cloneable. Thus the class implements three interfaces but does not have any logic within to support them beyond that supported by Foo.

That said, it's silly to take the SRP to extremes. If a class defines more than one method, is it violating the SRP? All Java Objects have a toString() method and an equals(Object) method, which means EVERY object in Java is responsible for both equality and self-representation. Is that a bad thing?

2

Not in my opinion. To me, a single responsibility is "model a user of my application". I may need to deliver that data via a web service, and store it in a relational database. I could provide that functionality by inheriting a couple of mix-in classes.

That doesn't mean the class has three responsibilities. It means that part of the responsibility to model a user requires supporting serialization and persistence.

1

I guess it depends on how you define the responsibility. In the classic iostream example it doesn't violate the SRP. The IOstream is responsible for managing one bidirectional stream.

After you run out of primitive responsibilities you move on to more generic high level responsibilities, after all how do you define the responsibility of your main entry point? Its responsibility has to be 'be the main entry point' not 'everything my app does' otherwise it is impossible to not violate the SRP and produce an application.

0

Not at all. Let’s say you have a button in the UI, and it’s responsibility is to start the process of deleting an address in the user’s address book.

The button also has the responsibility to process mouse clicks, to redraw itself when needed, change its appearance while highlighted, hide the background behind it, show or hide itself, change its Color or title as directed and so on. That’s at least a dozen responsibilities and violations of the dreaded “single responsibility principle”.

But that’s not how it works! Your button has one responsibility. Multiple inheritance has nothing to do with this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.