How do I avoid breaking the Liskov substitution principle with a class that implements multiple interfaces?












14















Given the following class:



class Example implements Interface1, Interface2{
...
}


When I instantiate the class using interface1:



Interface1 example = new Example();


Then I can call only the Interface1 methods, and not the Interface2 methods, unless I cast:



((Interface2) example).someInterface2Method();


Of course, to make this runtime safe, I should also wrap this with an instanceof check:



if (example instanceof Interface2) {
((Interface2) example).someInterface2Method();
}


I'm aware that I could have a wrapper interface that extends both interfaces, but then I could end up with multiple interfaces to cater for all the possible permutations of interfaces that can be implemented by the same class. The Interfaces in question do not naturally extend one another so inheritance also seems wrong.



Does the instanceof / cast approach break LSP as I am interrogating the runtime instance to determine its implementations? Whichever implementation I use seems to have some side-effect either in bad design or usage.










share|improve this question




















  • 14





    I wouldn't add the check. If I had to have both interfaces in play in a single scope I'd make the compile time type Example, not Interface1.

    – duffymo
    15 hours ago






  • 1





    You definitely don't need to cast in this situation. It should always be a last resort. Probably more than 90% of casts are simply a result of bad design.

    – Michael
    15 hours ago






  • 6





    create a third interface which extends those 2 you've mentioned and use the former throughout your code. or use generics to be more forgiving: public <T extends Interfac1 & Interface2> void doSomething(T t)

    – Lino
    15 hours ago








  • 5





    Can't you use Example example = new Example();?

    – Andy Turner
    15 hours ago











  • Given that casts are a reasonable feature of the Java language, we can't answer these questions without knowing the purpose of the class and interfaces and why you want to cast.

    – Matt Timmermans
    14 hours ago
















14















Given the following class:



class Example implements Interface1, Interface2{
...
}


When I instantiate the class using interface1:



Interface1 example = new Example();


Then I can call only the Interface1 methods, and not the Interface2 methods, unless I cast:



((Interface2) example).someInterface2Method();


Of course, to make this runtime safe, I should also wrap this with an instanceof check:



if (example instanceof Interface2) {
((Interface2) example).someInterface2Method();
}


I'm aware that I could have a wrapper interface that extends both interfaces, but then I could end up with multiple interfaces to cater for all the possible permutations of interfaces that can be implemented by the same class. The Interfaces in question do not naturally extend one another so inheritance also seems wrong.



Does the instanceof / cast approach break LSP as I am interrogating the runtime instance to determine its implementations? Whichever implementation I use seems to have some side-effect either in bad design or usage.










share|improve this question




















  • 14





    I wouldn't add the check. If I had to have both interfaces in play in a single scope I'd make the compile time type Example, not Interface1.

    – duffymo
    15 hours ago






  • 1





    You definitely don't need to cast in this situation. It should always be a last resort. Probably more than 90% of casts are simply a result of bad design.

    – Michael
    15 hours ago






  • 6





    create a third interface which extends those 2 you've mentioned and use the former throughout your code. or use generics to be more forgiving: public <T extends Interfac1 & Interface2> void doSomething(T t)

    – Lino
    15 hours ago








  • 5





    Can't you use Example example = new Example();?

    – Andy Turner
    15 hours ago











  • Given that casts are a reasonable feature of the Java language, we can't answer these questions without knowing the purpose of the class and interfaces and why you want to cast.

    – Matt Timmermans
    14 hours ago














14












14








14


4






Given the following class:



class Example implements Interface1, Interface2{
...
}


When I instantiate the class using interface1:



Interface1 example = new Example();


Then I can call only the Interface1 methods, and not the Interface2 methods, unless I cast:



((Interface2) example).someInterface2Method();


Of course, to make this runtime safe, I should also wrap this with an instanceof check:



if (example instanceof Interface2) {
((Interface2) example).someInterface2Method();
}


I'm aware that I could have a wrapper interface that extends both interfaces, but then I could end up with multiple interfaces to cater for all the possible permutations of interfaces that can be implemented by the same class. The Interfaces in question do not naturally extend one another so inheritance also seems wrong.



Does the instanceof / cast approach break LSP as I am interrogating the runtime instance to determine its implementations? Whichever implementation I use seems to have some side-effect either in bad design or usage.










share|improve this question
















Given the following class:



class Example implements Interface1, Interface2{
...
}


When I instantiate the class using interface1:



Interface1 example = new Example();


Then I can call only the Interface1 methods, and not the Interface2 methods, unless I cast:



((Interface2) example).someInterface2Method();


Of course, to make this runtime safe, I should also wrap this with an instanceof check:



if (example instanceof Interface2) {
((Interface2) example).someInterface2Method();
}


I'm aware that I could have a wrapper interface that extends both interfaces, but then I could end up with multiple interfaces to cater for all the possible permutations of interfaces that can be implemented by the same class. The Interfaces in question do not naturally extend one another so inheritance also seems wrong.



Does the instanceof / cast approach break LSP as I am interrogating the runtime instance to determine its implementations? Whichever implementation I use seems to have some side-effect either in bad design or usage.







java lsp






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 13 mins ago









Peter Mortensen

13.5k1984111




13.5k1984111










asked 15 hours ago









jmljml

713




713








  • 14





    I wouldn't add the check. If I had to have both interfaces in play in a single scope I'd make the compile time type Example, not Interface1.

    – duffymo
    15 hours ago






  • 1





    You definitely don't need to cast in this situation. It should always be a last resort. Probably more than 90% of casts are simply a result of bad design.

    – Michael
    15 hours ago






  • 6





    create a third interface which extends those 2 you've mentioned and use the former throughout your code. or use generics to be more forgiving: public <T extends Interfac1 & Interface2> void doSomething(T t)

    – Lino
    15 hours ago








  • 5





    Can't you use Example example = new Example();?

    – Andy Turner
    15 hours ago











  • Given that casts are a reasonable feature of the Java language, we can't answer these questions without knowing the purpose of the class and interfaces and why you want to cast.

    – Matt Timmermans
    14 hours ago














  • 14





    I wouldn't add the check. If I had to have both interfaces in play in a single scope I'd make the compile time type Example, not Interface1.

    – duffymo
    15 hours ago






  • 1





    You definitely don't need to cast in this situation. It should always be a last resort. Probably more than 90% of casts are simply a result of bad design.

    – Michael
    15 hours ago






  • 6





    create a third interface which extends those 2 you've mentioned and use the former throughout your code. or use generics to be more forgiving: public <T extends Interfac1 & Interface2> void doSomething(T t)

    – Lino
    15 hours ago








  • 5





    Can't you use Example example = new Example();?

    – Andy Turner
    15 hours ago











  • Given that casts are a reasonable feature of the Java language, we can't answer these questions without knowing the purpose of the class and interfaces and why you want to cast.

    – Matt Timmermans
    14 hours ago








14




14





I wouldn't add the check. If I had to have both interfaces in play in a single scope I'd make the compile time type Example, not Interface1.

– duffymo
15 hours ago





I wouldn't add the check. If I had to have both interfaces in play in a single scope I'd make the compile time type Example, not Interface1.

– duffymo
15 hours ago




1




1





You definitely don't need to cast in this situation. It should always be a last resort. Probably more than 90% of casts are simply a result of bad design.

– Michael
15 hours ago





You definitely don't need to cast in this situation. It should always be a last resort. Probably more than 90% of casts are simply a result of bad design.

– Michael
15 hours ago




6




6





create a third interface which extends those 2 you've mentioned and use the former throughout your code. or use generics to be more forgiving: public <T extends Interfac1 & Interface2> void doSomething(T t)

– Lino
15 hours ago







create a third interface which extends those 2 you've mentioned and use the former throughout your code. or use generics to be more forgiving: public <T extends Interfac1 & Interface2> void doSomething(T t)

– Lino
15 hours ago






5




5





Can't you use Example example = new Example();?

– Andy Turner
15 hours ago





Can't you use Example example = new Example();?

– Andy Turner
15 hours ago













Given that casts are a reasonable feature of the Java language, we can't answer these questions without knowing the purpose of the class and interfaces and why you want to cast.

– Matt Timmermans
14 hours ago





Given that casts are a reasonable feature of the Java language, we can't answer these questions without knowing the purpose of the class and interfaces and why you want to cast.

– Matt Timmermans
14 hours ago












6 Answers
6






active

oldest

votes


















14















I'm aware that I could have a wrapper interface that extends both
interfaces, but then I could end up with multiple interfaces to cater
for all the possible permutations of interfaces that can be
implemented by the same class




I suspect that if you're finding that lots of your classes implement different combinations of interfaces then either: your concrete classes are doing too much; or (less likely) your interfaces are too small and too specialised, to the point of being useless individually.



If you have good reason for some code to require something that is both a Interface1 and a Interface2 then absolutely go ahead and make a combined version that extends both. If you struggle to think of an appropriate name for this (no, not FooAndBar) then that's an indicator that your design is wrong.



Absolutely do not rely on casting anything. It should only be used as a last resort and usually only for very specific problems (e.g. serialization).



My favourite and most-used design pattern is the decorator pattern as such most of my classes will only ever implement one interface (except for more generic interfaces such as Comparable). I would say that if your classes are frequently/always implementing more than one interface then that's a code smell.





If you're instantiating the object and using it within the same scope then you should just be writing



Example example = new Example();


Just so it's clear (I'm not sure if this is what you were suggesting), under no circumstances should you ever be writing anything like this:



Interface1 example = new Example();
if (example instanceof Interface2) {
((Interface2) example).someInterface2Method();
}





share|improve this answer


























  • It is an interesting point you make when you say "to the point of being useless individually" - Interface2 in this example actually refers to an interface I have called HasParameters, which has methods getParams() and setParams() as not all implementations of Interface1 actually need to work with params. I was attempting to not break the Interface Segregation Principle, by having lots of implementations with empty getParams() and setParams() methods but like you say, Interface2 is pretty useless on its own...

    – jml
    15 hours ago








  • 2





    @jml then maybe a specification of Interface1 with your said methods would be better (interface Interface2 extends Interface1 { /* get and set params */ }

    – Lino
    14 hours ago






  • 1





    @jml Then what Lino suggests is probably what you want. Request and ParametizedRequest are better than Request and HasParameters.

    – Michael
    14 hours ago






  • 2





    @jml HasParameters doesn't feel like an interface, but an attribute. Maybe in reality what you need to do is add the methods to Request, like hasParameters(), getParameters() and setParameters(). With Java 8 you can even have those default to false, emptyList() and throw OperationNotSupportedException respectively if you don't want to have to implement them all the time. Java's Collection classes do this all the time.

    – jbx
    11 hours ago








  • 1





    With Java 8 you could include your getParams() and setParams() in Interface1 with default do-nothing implementations, like public default void setParams(Params p) {} and public default Params getParams() { return null; }

    – Stephen P
    10 hours ago



















10














Your class can implement multiple interfaces fine, and it is not breaking any OOP principles. On the contrary, it is following the interface segregation principle.



It is confusing why would you have a situation where something of type Interface1 is expected to provide someInterface2Method(). That is where your design is wrong.



Think about it in a slightly different way: Where you have void method1(Interface1 interface1), you wouldn't expect this to expect interface1 to also be an instance of Interface2. If it was the case, the type of the argument should have been different.



If you want to be able to call both methods, you should have the type of your variable example set to Example. That way you avoid the instanceof and type casting altogether.



If your two interfaces Interface1 and Interface2 are not that loosely coupled, and you will often need to call methods from both, maybe separating the interfaces wasn't such a good idea, or maybe you want to have another interface which extends both.



In general (although not always), instanceof checks and type casts often indicate some OO design flaw. Sometimes the design would fit for the rest of the program, but you would have a small case where it is simpler to type cast rather than refactor everything. But if possible you should always strive to avoid it at first, as part of your design.






share|improve this answer

































    5














    You have two different options (I bet there are a lot more).



    The first is to create your own interface which extends the other two:



    interface Interface3 extends Interface1, Interface2 {}


    And then use that throughout your code:



    public void doSomething(Interface3 interface3){
    ...
    }


    The other way (and in my opinion the better one) is to use generics per method:



    public <T extends Interface1 & Interface2> void doSomething(T t){
    ...
    }


    The latter option is in fact less restricted than the former, because the generic type T gets dynamically inferred and thus leads to less coupling (a class doesn't have to implement a specific grouping interface, like the first example).






    share|improve this answer





















    • 1





      "And then use that throughout your code" The significant downside to this is that you have to make Example (and any other classes) implement this class.

      – Andy Turner
      15 hours ago











    • @Andy I agree and that's why the second approach is more flexible and may probably be preferred

      – Lino
      15 hours ago






    • 5





      It's worth stating your preferred option first; or, at the very least, stating "My preferred way" or similar, which is a much stronger endorsement than "the other way".

      – Andy Turner
      15 hours ago






    • 3





      While you are providing correct technical solutions to the issue, be wary of implementing workarounds when the underlying issue is an architecture one. You may find yourself with even more issues in the end stemming from an incorrect design.

      – Vincent Savard
      11 hours ago





















    4














    Your example does not break LSV, but it seems to break SRP. If you encounter such case where you need to cast an object to its 2nd interface, the method that contains such code can be considered busy.



    Implementing 2 (or more) interfaces in a class is fine. In deciding which interface to use as its data type depends entirely on the context of the code that will use it.



    Casting is fine, especially when changing context.



    class Payment implements Expirable, Limited {
    /* ... */
    }

    class PaymentProcessor {
    // Using payment here because i'm working with payments.
    public void process(Payment payment) {
    boolean expired = expirationChecker.check(payment);
    boolean pastLimit = limitChecker.check(payment);

    if (!expired && !pastLimit) {
    acceptPayment(payment);
    }
    }
    }

    class ExpirationChecker {
    // This the `Expirable` world, so i'm using Expirable here
    public boolean check(Expirable expirable) {
    // code
    }
    }

    class LimitChecker {
    // This class is about checking limits, thats why im using `Limited` here
    public boolean check(Limited limited) {
    // code
    }
    }





    share|improve this answer
























    • LSV? Don't you mean LSP?

      – Peter Mortensen
      10 mins ago



















    1














    Usually, many, client-specific interfaces are fine, and somewhat part of the Interface segregation principle (the "I" in SOLID). Some more specific points, on a technical level, have already been mentioned in other answers.



    Particularly that you can go too far with this segregation, by having a class like



    class Person implements FirstNameProvider, LastNameProvider, AgeProvider ... {
    @Override String getFirstName() {...}
    @Override String getLastName() {...}
    @Override int getAge() {...}
    ...
    }


    Or, conversely, that you have an implementing class that is too powerful, as in



    class Application implements DatabaseReader, DataProcessor, UserInteraction, Visualizer {
    ...
    }




    I think that the main point in the Interface Segregation Principle is that the interfaces should be client-specific. They should basically "summarize" the functions that are required by a certain client, for a certain task.



    To put it that way: The issue is to strike the right balance between the extremes that I sketched above. When I'm trying to figure out interfaces and their relationships (mutually, and in terms of the classes that implement them), I always try to take a step back and ask myself, in an intentionally naïve way: Who is going to receive what, and what is he going to do with it?



    Regarding your example: When all your clients always need the functionality of Interface1 and Interface2 at the same time, then you should consider either defining an



    interface Combined extends Interface1, Interface2 { }


    or not have different interfaces in the first place. On the other hand, when the functionalities are completely distinct and unrelated and never used together, then you should wonder why the single class is implementing them at the same time.



    At this point, one could refer to another principle, namely Composition over inheritance. Although it is not classically related to implementing multiple interfaces, composition can also be favorable in this case. For example, you could change your class to not implement the interfaces directly, but only provide instances that implement them:



    class Example {
    Interface1 getInterface1() { ... }
    Interface2 getInterface2() { ... }
    }


    (Note: It looks a bit odd in this Example (sic!), but depending on the complexity of the implementation of Interface1 and Interface2, it can really make sense to keep them separated)






    share|improve this answer
























    • This is the correct answer. The interface is built for the contract that the client code needs fulfilled. If the client code reasonably expects to be able to call someInterface1Method AND someInterface2Method, then that is a new contract. From wikipedia on ISP: "no client should be forced to depend on methods it does not use." and "clients will only have to know about the methods that are of interest to them."

      – Xtros
      6 hours ago





















    0














    The problem you describe often comes about through over-zealous application of the Interface Segregation Principle, encouraged by languages' inability to specify that members of one interface should, by default, be chained to static methods which could implement sensible behaviors.



    Consider, for example, a basic sequence/enumeration interface and the following behaviors:




    1. Produce an enumerator which can read out the objects if no other iterator has yet been created.


    2. Produce an enumerator which can read out the objects even if another iterator has already been created and used.


    3. Report how many items are in the sequence


    4. Report the value of the Nth item in the sequence


    5. Copy a range of items from the object into an array of that type.


    6. Yield a reference to an immutable object that can accommodate the above operations efficiently with contents that are guaranteed never to change.



    I would suggest that such abilities should be part of the basic sequence/enumeration interface, along with a method/property to indicate which of the above operations are meaningfully supported. Some kinds of single-shot on-demand enumerators (e.g. an infinite truly-random sequence generator) might not be able to support any of those functions, but segregating such functions into separate interfaces will make it much harder to produce efficient wrappers for many kinds of operations.



    One could produce a wrapper class that would accommodate all of the above operations, though not necessarily efficiently, on any finite sequence which supports the first ability. If, however, the class is being used to wrap an object that already supports some of those abilities (e.g. access the Nth item), having the wrapper use the underlying behaviors could be much more efficient than having it do everything via the second function above (e.g. creating a new enumerator, and using that to iteratively read and ignore items from the sequence until the desired one is reached).



    Having all objects that produce any kind of sequence support an interface that includes all of the above, along with an indication of what abilities are supported, would be cleaner than trying to have different interfaces for different subsets of abilities, and requiring that wrapper classes make explicit provision for any combinations they want to expose to their clients.






    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54184354%2fhow-do-i-avoid-breaking-the-liskov-substitution-principle-with-a-class-that-impl%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      6 Answers
      6






      active

      oldest

      votes








      6 Answers
      6






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      14















      I'm aware that I could have a wrapper interface that extends both
      interfaces, but then I could end up with multiple interfaces to cater
      for all the possible permutations of interfaces that can be
      implemented by the same class




      I suspect that if you're finding that lots of your classes implement different combinations of interfaces then either: your concrete classes are doing too much; or (less likely) your interfaces are too small and too specialised, to the point of being useless individually.



      If you have good reason for some code to require something that is both a Interface1 and a Interface2 then absolutely go ahead and make a combined version that extends both. If you struggle to think of an appropriate name for this (no, not FooAndBar) then that's an indicator that your design is wrong.



      Absolutely do not rely on casting anything. It should only be used as a last resort and usually only for very specific problems (e.g. serialization).



      My favourite and most-used design pattern is the decorator pattern as such most of my classes will only ever implement one interface (except for more generic interfaces such as Comparable). I would say that if your classes are frequently/always implementing more than one interface then that's a code smell.





      If you're instantiating the object and using it within the same scope then you should just be writing



      Example example = new Example();


      Just so it's clear (I'm not sure if this is what you were suggesting), under no circumstances should you ever be writing anything like this:



      Interface1 example = new Example();
      if (example instanceof Interface2) {
      ((Interface2) example).someInterface2Method();
      }





      share|improve this answer


























      • It is an interesting point you make when you say "to the point of being useless individually" - Interface2 in this example actually refers to an interface I have called HasParameters, which has methods getParams() and setParams() as not all implementations of Interface1 actually need to work with params. I was attempting to not break the Interface Segregation Principle, by having lots of implementations with empty getParams() and setParams() methods but like you say, Interface2 is pretty useless on its own...

        – jml
        15 hours ago








      • 2





        @jml then maybe a specification of Interface1 with your said methods would be better (interface Interface2 extends Interface1 { /* get and set params */ }

        – Lino
        14 hours ago






      • 1





        @jml Then what Lino suggests is probably what you want. Request and ParametizedRequest are better than Request and HasParameters.

        – Michael
        14 hours ago






      • 2





        @jml HasParameters doesn't feel like an interface, but an attribute. Maybe in reality what you need to do is add the methods to Request, like hasParameters(), getParameters() and setParameters(). With Java 8 you can even have those default to false, emptyList() and throw OperationNotSupportedException respectively if you don't want to have to implement them all the time. Java's Collection classes do this all the time.

        – jbx
        11 hours ago








      • 1





        With Java 8 you could include your getParams() and setParams() in Interface1 with default do-nothing implementations, like public default void setParams(Params p) {} and public default Params getParams() { return null; }

        – Stephen P
        10 hours ago
















      14















      I'm aware that I could have a wrapper interface that extends both
      interfaces, but then I could end up with multiple interfaces to cater
      for all the possible permutations of interfaces that can be
      implemented by the same class




      I suspect that if you're finding that lots of your classes implement different combinations of interfaces then either: your concrete classes are doing too much; or (less likely) your interfaces are too small and too specialised, to the point of being useless individually.



      If you have good reason for some code to require something that is both a Interface1 and a Interface2 then absolutely go ahead and make a combined version that extends both. If you struggle to think of an appropriate name for this (no, not FooAndBar) then that's an indicator that your design is wrong.



      Absolutely do not rely on casting anything. It should only be used as a last resort and usually only for very specific problems (e.g. serialization).



      My favourite and most-used design pattern is the decorator pattern as such most of my classes will only ever implement one interface (except for more generic interfaces such as Comparable). I would say that if your classes are frequently/always implementing more than one interface then that's a code smell.





      If you're instantiating the object and using it within the same scope then you should just be writing



      Example example = new Example();


      Just so it's clear (I'm not sure if this is what you were suggesting), under no circumstances should you ever be writing anything like this:



      Interface1 example = new Example();
      if (example instanceof Interface2) {
      ((Interface2) example).someInterface2Method();
      }





      share|improve this answer


























      • It is an interesting point you make when you say "to the point of being useless individually" - Interface2 in this example actually refers to an interface I have called HasParameters, which has methods getParams() and setParams() as not all implementations of Interface1 actually need to work with params. I was attempting to not break the Interface Segregation Principle, by having lots of implementations with empty getParams() and setParams() methods but like you say, Interface2 is pretty useless on its own...

        – jml
        15 hours ago








      • 2





        @jml then maybe a specification of Interface1 with your said methods would be better (interface Interface2 extends Interface1 { /* get and set params */ }

        – Lino
        14 hours ago






      • 1





        @jml Then what Lino suggests is probably what you want. Request and ParametizedRequest are better than Request and HasParameters.

        – Michael
        14 hours ago






      • 2





        @jml HasParameters doesn't feel like an interface, but an attribute. Maybe in reality what you need to do is add the methods to Request, like hasParameters(), getParameters() and setParameters(). With Java 8 you can even have those default to false, emptyList() and throw OperationNotSupportedException respectively if you don't want to have to implement them all the time. Java's Collection classes do this all the time.

        – jbx
        11 hours ago








      • 1





        With Java 8 you could include your getParams() and setParams() in Interface1 with default do-nothing implementations, like public default void setParams(Params p) {} and public default Params getParams() { return null; }

        – Stephen P
        10 hours ago














      14












      14








      14








      I'm aware that I could have a wrapper interface that extends both
      interfaces, but then I could end up with multiple interfaces to cater
      for all the possible permutations of interfaces that can be
      implemented by the same class




      I suspect that if you're finding that lots of your classes implement different combinations of interfaces then either: your concrete classes are doing too much; or (less likely) your interfaces are too small and too specialised, to the point of being useless individually.



      If you have good reason for some code to require something that is both a Interface1 and a Interface2 then absolutely go ahead and make a combined version that extends both. If you struggle to think of an appropriate name for this (no, not FooAndBar) then that's an indicator that your design is wrong.



      Absolutely do not rely on casting anything. It should only be used as a last resort and usually only for very specific problems (e.g. serialization).



      My favourite and most-used design pattern is the decorator pattern as such most of my classes will only ever implement one interface (except for more generic interfaces such as Comparable). I would say that if your classes are frequently/always implementing more than one interface then that's a code smell.





      If you're instantiating the object and using it within the same scope then you should just be writing



      Example example = new Example();


      Just so it's clear (I'm not sure if this is what you were suggesting), under no circumstances should you ever be writing anything like this:



      Interface1 example = new Example();
      if (example instanceof Interface2) {
      ((Interface2) example).someInterface2Method();
      }





      share|improve this answer
















      I'm aware that I could have a wrapper interface that extends both
      interfaces, but then I could end up with multiple interfaces to cater
      for all the possible permutations of interfaces that can be
      implemented by the same class




      I suspect that if you're finding that lots of your classes implement different combinations of interfaces then either: your concrete classes are doing too much; or (less likely) your interfaces are too small and too specialised, to the point of being useless individually.



      If you have good reason for some code to require something that is both a Interface1 and a Interface2 then absolutely go ahead and make a combined version that extends both. If you struggle to think of an appropriate name for this (no, not FooAndBar) then that's an indicator that your design is wrong.



      Absolutely do not rely on casting anything. It should only be used as a last resort and usually only for very specific problems (e.g. serialization).



      My favourite and most-used design pattern is the decorator pattern as such most of my classes will only ever implement one interface (except for more generic interfaces such as Comparable). I would say that if your classes are frequently/always implementing more than one interface then that's a code smell.





      If you're instantiating the object and using it within the same scope then you should just be writing



      Example example = new Example();


      Just so it's clear (I'm not sure if this is what you were suggesting), under no circumstances should you ever be writing anything like this:



      Interface1 example = new Example();
      if (example instanceof Interface2) {
      ((Interface2) example).someInterface2Method();
      }






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited 15 hours ago

























      answered 15 hours ago









      MichaelMichael

      18.9k73369




      18.9k73369













      • It is an interesting point you make when you say "to the point of being useless individually" - Interface2 in this example actually refers to an interface I have called HasParameters, which has methods getParams() and setParams() as not all implementations of Interface1 actually need to work with params. I was attempting to not break the Interface Segregation Principle, by having lots of implementations with empty getParams() and setParams() methods but like you say, Interface2 is pretty useless on its own...

        – jml
        15 hours ago








      • 2





        @jml then maybe a specification of Interface1 with your said methods would be better (interface Interface2 extends Interface1 { /* get and set params */ }

        – Lino
        14 hours ago






      • 1





        @jml Then what Lino suggests is probably what you want. Request and ParametizedRequest are better than Request and HasParameters.

        – Michael
        14 hours ago






      • 2





        @jml HasParameters doesn't feel like an interface, but an attribute. Maybe in reality what you need to do is add the methods to Request, like hasParameters(), getParameters() and setParameters(). With Java 8 you can even have those default to false, emptyList() and throw OperationNotSupportedException respectively if you don't want to have to implement them all the time. Java's Collection classes do this all the time.

        – jbx
        11 hours ago








      • 1





        With Java 8 you could include your getParams() and setParams() in Interface1 with default do-nothing implementations, like public default void setParams(Params p) {} and public default Params getParams() { return null; }

        – Stephen P
        10 hours ago



















      • It is an interesting point you make when you say "to the point of being useless individually" - Interface2 in this example actually refers to an interface I have called HasParameters, which has methods getParams() and setParams() as not all implementations of Interface1 actually need to work with params. I was attempting to not break the Interface Segregation Principle, by having lots of implementations with empty getParams() and setParams() methods but like you say, Interface2 is pretty useless on its own...

        – jml
        15 hours ago








      • 2





        @jml then maybe a specification of Interface1 with your said methods would be better (interface Interface2 extends Interface1 { /* get and set params */ }

        – Lino
        14 hours ago






      • 1





        @jml Then what Lino suggests is probably what you want. Request and ParametizedRequest are better than Request and HasParameters.

        – Michael
        14 hours ago






      • 2





        @jml HasParameters doesn't feel like an interface, but an attribute. Maybe in reality what you need to do is add the methods to Request, like hasParameters(), getParameters() and setParameters(). With Java 8 you can even have those default to false, emptyList() and throw OperationNotSupportedException respectively if you don't want to have to implement them all the time. Java's Collection classes do this all the time.

        – jbx
        11 hours ago








      • 1





        With Java 8 you could include your getParams() and setParams() in Interface1 with default do-nothing implementations, like public default void setParams(Params p) {} and public default Params getParams() { return null; }

        – Stephen P
        10 hours ago

















      It is an interesting point you make when you say "to the point of being useless individually" - Interface2 in this example actually refers to an interface I have called HasParameters, which has methods getParams() and setParams() as not all implementations of Interface1 actually need to work with params. I was attempting to not break the Interface Segregation Principle, by having lots of implementations with empty getParams() and setParams() methods but like you say, Interface2 is pretty useless on its own...

      – jml
      15 hours ago







      It is an interesting point you make when you say "to the point of being useless individually" - Interface2 in this example actually refers to an interface I have called HasParameters, which has methods getParams() and setParams() as not all implementations of Interface1 actually need to work with params. I was attempting to not break the Interface Segregation Principle, by having lots of implementations with empty getParams() and setParams() methods but like you say, Interface2 is pretty useless on its own...

      – jml
      15 hours ago






      2




      2





      @jml then maybe a specification of Interface1 with your said methods would be better (interface Interface2 extends Interface1 { /* get and set params */ }

      – Lino
      14 hours ago





      @jml then maybe a specification of Interface1 with your said methods would be better (interface Interface2 extends Interface1 { /* get and set params */ }

      – Lino
      14 hours ago




      1




      1





      @jml Then what Lino suggests is probably what you want. Request and ParametizedRequest are better than Request and HasParameters.

      – Michael
      14 hours ago





      @jml Then what Lino suggests is probably what you want. Request and ParametizedRequest are better than Request and HasParameters.

      – Michael
      14 hours ago




      2




      2





      @jml HasParameters doesn't feel like an interface, but an attribute. Maybe in reality what you need to do is add the methods to Request, like hasParameters(), getParameters() and setParameters(). With Java 8 you can even have those default to false, emptyList() and throw OperationNotSupportedException respectively if you don't want to have to implement them all the time. Java's Collection classes do this all the time.

      – jbx
      11 hours ago







      @jml HasParameters doesn't feel like an interface, but an attribute. Maybe in reality what you need to do is add the methods to Request, like hasParameters(), getParameters() and setParameters(). With Java 8 you can even have those default to false, emptyList() and throw OperationNotSupportedException respectively if you don't want to have to implement them all the time. Java's Collection classes do this all the time.

      – jbx
      11 hours ago






      1




      1





      With Java 8 you could include your getParams() and setParams() in Interface1 with default do-nothing implementations, like public default void setParams(Params p) {} and public default Params getParams() { return null; }

      – Stephen P
      10 hours ago





      With Java 8 you could include your getParams() and setParams() in Interface1 with default do-nothing implementations, like public default void setParams(Params p) {} and public default Params getParams() { return null; }

      – Stephen P
      10 hours ago













      10














      Your class can implement multiple interfaces fine, and it is not breaking any OOP principles. On the contrary, it is following the interface segregation principle.



      It is confusing why would you have a situation where something of type Interface1 is expected to provide someInterface2Method(). That is where your design is wrong.



      Think about it in a slightly different way: Where you have void method1(Interface1 interface1), you wouldn't expect this to expect interface1 to also be an instance of Interface2. If it was the case, the type of the argument should have been different.



      If you want to be able to call both methods, you should have the type of your variable example set to Example. That way you avoid the instanceof and type casting altogether.



      If your two interfaces Interface1 and Interface2 are not that loosely coupled, and you will often need to call methods from both, maybe separating the interfaces wasn't such a good idea, or maybe you want to have another interface which extends both.



      In general (although not always), instanceof checks and type casts often indicate some OO design flaw. Sometimes the design would fit for the rest of the program, but you would have a small case where it is simpler to type cast rather than refactor everything. But if possible you should always strive to avoid it at first, as part of your design.






      share|improve this answer






























        10














        Your class can implement multiple interfaces fine, and it is not breaking any OOP principles. On the contrary, it is following the interface segregation principle.



        It is confusing why would you have a situation where something of type Interface1 is expected to provide someInterface2Method(). That is where your design is wrong.



        Think about it in a slightly different way: Where you have void method1(Interface1 interface1), you wouldn't expect this to expect interface1 to also be an instance of Interface2. If it was the case, the type of the argument should have been different.



        If you want to be able to call both methods, you should have the type of your variable example set to Example. That way you avoid the instanceof and type casting altogether.



        If your two interfaces Interface1 and Interface2 are not that loosely coupled, and you will often need to call methods from both, maybe separating the interfaces wasn't such a good idea, or maybe you want to have another interface which extends both.



        In general (although not always), instanceof checks and type casts often indicate some OO design flaw. Sometimes the design would fit for the rest of the program, but you would have a small case where it is simpler to type cast rather than refactor everything. But if possible you should always strive to avoid it at first, as part of your design.






        share|improve this answer




























          10












          10








          10







          Your class can implement multiple interfaces fine, and it is not breaking any OOP principles. On the contrary, it is following the interface segregation principle.



          It is confusing why would you have a situation where something of type Interface1 is expected to provide someInterface2Method(). That is where your design is wrong.



          Think about it in a slightly different way: Where you have void method1(Interface1 interface1), you wouldn't expect this to expect interface1 to also be an instance of Interface2. If it was the case, the type of the argument should have been different.



          If you want to be able to call both methods, you should have the type of your variable example set to Example. That way you avoid the instanceof and type casting altogether.



          If your two interfaces Interface1 and Interface2 are not that loosely coupled, and you will often need to call methods from both, maybe separating the interfaces wasn't such a good idea, or maybe you want to have another interface which extends both.



          In general (although not always), instanceof checks and type casts often indicate some OO design flaw. Sometimes the design would fit for the rest of the program, but you would have a small case where it is simpler to type cast rather than refactor everything. But if possible you should always strive to avoid it at first, as part of your design.






          share|improve this answer















          Your class can implement multiple interfaces fine, and it is not breaking any OOP principles. On the contrary, it is following the interface segregation principle.



          It is confusing why would you have a situation where something of type Interface1 is expected to provide someInterface2Method(). That is where your design is wrong.



          Think about it in a slightly different way: Where you have void method1(Interface1 interface1), you wouldn't expect this to expect interface1 to also be an instance of Interface2. If it was the case, the type of the argument should have been different.



          If you want to be able to call both methods, you should have the type of your variable example set to Example. That way you avoid the instanceof and type casting altogether.



          If your two interfaces Interface1 and Interface2 are not that loosely coupled, and you will often need to call methods from both, maybe separating the interfaces wasn't such a good idea, or maybe you want to have another interface which extends both.



          In general (although not always), instanceof checks and type casts often indicate some OO design flaw. Sometimes the design would fit for the rest of the program, but you would have a small case where it is simpler to type cast rather than refactor everything. But if possible you should always strive to avoid it at first, as part of your design.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 5 mins ago









          Peter Mortensen

          13.5k1984111




          13.5k1984111










          answered 14 hours ago









          jbxjbx

          10.8k1057111




          10.8k1057111























              5














              You have two different options (I bet there are a lot more).



              The first is to create your own interface which extends the other two:



              interface Interface3 extends Interface1, Interface2 {}


              And then use that throughout your code:



              public void doSomething(Interface3 interface3){
              ...
              }


              The other way (and in my opinion the better one) is to use generics per method:



              public <T extends Interface1 & Interface2> void doSomething(T t){
              ...
              }


              The latter option is in fact less restricted than the former, because the generic type T gets dynamically inferred and thus leads to less coupling (a class doesn't have to implement a specific grouping interface, like the first example).






              share|improve this answer





















              • 1





                "And then use that throughout your code" The significant downside to this is that you have to make Example (and any other classes) implement this class.

                – Andy Turner
                15 hours ago











              • @Andy I agree and that's why the second approach is more flexible and may probably be preferred

                – Lino
                15 hours ago






              • 5





                It's worth stating your preferred option first; or, at the very least, stating "My preferred way" or similar, which is a much stronger endorsement than "the other way".

                – Andy Turner
                15 hours ago






              • 3





                While you are providing correct technical solutions to the issue, be wary of implementing workarounds when the underlying issue is an architecture one. You may find yourself with even more issues in the end stemming from an incorrect design.

                – Vincent Savard
                11 hours ago


















              5














              You have two different options (I bet there are a lot more).



              The first is to create your own interface which extends the other two:



              interface Interface3 extends Interface1, Interface2 {}


              And then use that throughout your code:



              public void doSomething(Interface3 interface3){
              ...
              }


              The other way (and in my opinion the better one) is to use generics per method:



              public <T extends Interface1 & Interface2> void doSomething(T t){
              ...
              }


              The latter option is in fact less restricted than the former, because the generic type T gets dynamically inferred and thus leads to less coupling (a class doesn't have to implement a specific grouping interface, like the first example).






              share|improve this answer





















              • 1





                "And then use that throughout your code" The significant downside to this is that you have to make Example (and any other classes) implement this class.

                – Andy Turner
                15 hours ago











              • @Andy I agree and that's why the second approach is more flexible and may probably be preferred

                – Lino
                15 hours ago






              • 5





                It's worth stating your preferred option first; or, at the very least, stating "My preferred way" or similar, which is a much stronger endorsement than "the other way".

                – Andy Turner
                15 hours ago






              • 3





                While you are providing correct technical solutions to the issue, be wary of implementing workarounds when the underlying issue is an architecture one. You may find yourself with even more issues in the end stemming from an incorrect design.

                – Vincent Savard
                11 hours ago
















              5












              5








              5







              You have two different options (I bet there are a lot more).



              The first is to create your own interface which extends the other two:



              interface Interface3 extends Interface1, Interface2 {}


              And then use that throughout your code:



              public void doSomething(Interface3 interface3){
              ...
              }


              The other way (and in my opinion the better one) is to use generics per method:



              public <T extends Interface1 & Interface2> void doSomething(T t){
              ...
              }


              The latter option is in fact less restricted than the former, because the generic type T gets dynamically inferred and thus leads to less coupling (a class doesn't have to implement a specific grouping interface, like the first example).






              share|improve this answer















              You have two different options (I bet there are a lot more).



              The first is to create your own interface which extends the other two:



              interface Interface3 extends Interface1, Interface2 {}


              And then use that throughout your code:



              public void doSomething(Interface3 interface3){
              ...
              }


              The other way (and in my opinion the better one) is to use generics per method:



              public <T extends Interface1 & Interface2> void doSomething(T t){
              ...
              }


              The latter option is in fact less restricted than the former, because the generic type T gets dynamically inferred and thus leads to less coupling (a class doesn't have to implement a specific grouping interface, like the first example).







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited 12 mins ago









              Peter Mortensen

              13.5k1984111




              13.5k1984111










              answered 15 hours ago









              LinoLino

              7,60621936




              7,60621936








              • 1





                "And then use that throughout your code" The significant downside to this is that you have to make Example (and any other classes) implement this class.

                – Andy Turner
                15 hours ago











              • @Andy I agree and that's why the second approach is more flexible and may probably be preferred

                – Lino
                15 hours ago






              • 5





                It's worth stating your preferred option first; or, at the very least, stating "My preferred way" or similar, which is a much stronger endorsement than "the other way".

                – Andy Turner
                15 hours ago






              • 3





                While you are providing correct technical solutions to the issue, be wary of implementing workarounds when the underlying issue is an architecture one. You may find yourself with even more issues in the end stemming from an incorrect design.

                – Vincent Savard
                11 hours ago
















              • 1





                "And then use that throughout your code" The significant downside to this is that you have to make Example (and any other classes) implement this class.

                – Andy Turner
                15 hours ago











              • @Andy I agree and that's why the second approach is more flexible and may probably be preferred

                – Lino
                15 hours ago






              • 5





                It's worth stating your preferred option first; or, at the very least, stating "My preferred way" or similar, which is a much stronger endorsement than "the other way".

                – Andy Turner
                15 hours ago






              • 3





                While you are providing correct technical solutions to the issue, be wary of implementing workarounds when the underlying issue is an architecture one. You may find yourself with even more issues in the end stemming from an incorrect design.

                – Vincent Savard
                11 hours ago










              1




              1





              "And then use that throughout your code" The significant downside to this is that you have to make Example (and any other classes) implement this class.

              – Andy Turner
              15 hours ago





              "And then use that throughout your code" The significant downside to this is that you have to make Example (and any other classes) implement this class.

              – Andy Turner
              15 hours ago













              @Andy I agree and that's why the second approach is more flexible and may probably be preferred

              – Lino
              15 hours ago





              @Andy I agree and that's why the second approach is more flexible and may probably be preferred

              – Lino
              15 hours ago




              5




              5





              It's worth stating your preferred option first; or, at the very least, stating "My preferred way" or similar, which is a much stronger endorsement than "the other way".

              – Andy Turner
              15 hours ago





              It's worth stating your preferred option first; or, at the very least, stating "My preferred way" or similar, which is a much stronger endorsement than "the other way".

              – Andy Turner
              15 hours ago




              3




              3





              While you are providing correct technical solutions to the issue, be wary of implementing workarounds when the underlying issue is an architecture one. You may find yourself with even more issues in the end stemming from an incorrect design.

              – Vincent Savard
              11 hours ago







              While you are providing correct technical solutions to the issue, be wary of implementing workarounds when the underlying issue is an architecture one. You may find yourself with even more issues in the end stemming from an incorrect design.

              – Vincent Savard
              11 hours ago













              4














              Your example does not break LSV, but it seems to break SRP. If you encounter such case where you need to cast an object to its 2nd interface, the method that contains such code can be considered busy.



              Implementing 2 (or more) interfaces in a class is fine. In deciding which interface to use as its data type depends entirely on the context of the code that will use it.



              Casting is fine, especially when changing context.



              class Payment implements Expirable, Limited {
              /* ... */
              }

              class PaymentProcessor {
              // Using payment here because i'm working with payments.
              public void process(Payment payment) {
              boolean expired = expirationChecker.check(payment);
              boolean pastLimit = limitChecker.check(payment);

              if (!expired && !pastLimit) {
              acceptPayment(payment);
              }
              }
              }

              class ExpirationChecker {
              // This the `Expirable` world, so i'm using Expirable here
              public boolean check(Expirable expirable) {
              // code
              }
              }

              class LimitChecker {
              // This class is about checking limits, thats why im using `Limited` here
              public boolean check(Limited limited) {
              // code
              }
              }





              share|improve this answer
























              • LSV? Don't you mean LSP?

                – Peter Mortensen
                10 mins ago
















              4














              Your example does not break LSV, but it seems to break SRP. If you encounter such case where you need to cast an object to its 2nd interface, the method that contains such code can be considered busy.



              Implementing 2 (or more) interfaces in a class is fine. In deciding which interface to use as its data type depends entirely on the context of the code that will use it.



              Casting is fine, especially when changing context.



              class Payment implements Expirable, Limited {
              /* ... */
              }

              class PaymentProcessor {
              // Using payment here because i'm working with payments.
              public void process(Payment payment) {
              boolean expired = expirationChecker.check(payment);
              boolean pastLimit = limitChecker.check(payment);

              if (!expired && !pastLimit) {
              acceptPayment(payment);
              }
              }
              }

              class ExpirationChecker {
              // This the `Expirable` world, so i'm using Expirable here
              public boolean check(Expirable expirable) {
              // code
              }
              }

              class LimitChecker {
              // This class is about checking limits, thats why im using `Limited` here
              public boolean check(Limited limited) {
              // code
              }
              }





              share|improve this answer
























              • LSV? Don't you mean LSP?

                – Peter Mortensen
                10 mins ago














              4












              4








              4







              Your example does not break LSV, but it seems to break SRP. If you encounter such case where you need to cast an object to its 2nd interface, the method that contains such code can be considered busy.



              Implementing 2 (or more) interfaces in a class is fine. In deciding which interface to use as its data type depends entirely on the context of the code that will use it.



              Casting is fine, especially when changing context.



              class Payment implements Expirable, Limited {
              /* ... */
              }

              class PaymentProcessor {
              // Using payment here because i'm working with payments.
              public void process(Payment payment) {
              boolean expired = expirationChecker.check(payment);
              boolean pastLimit = limitChecker.check(payment);

              if (!expired && !pastLimit) {
              acceptPayment(payment);
              }
              }
              }

              class ExpirationChecker {
              // This the `Expirable` world, so i'm using Expirable here
              public boolean check(Expirable expirable) {
              // code
              }
              }

              class LimitChecker {
              // This class is about checking limits, thats why im using `Limited` here
              public boolean check(Limited limited) {
              // code
              }
              }





              share|improve this answer













              Your example does not break LSV, but it seems to break SRP. If you encounter such case where you need to cast an object to its 2nd interface, the method that contains such code can be considered busy.



              Implementing 2 (or more) interfaces in a class is fine. In deciding which interface to use as its data type depends entirely on the context of the code that will use it.



              Casting is fine, especially when changing context.



              class Payment implements Expirable, Limited {
              /* ... */
              }

              class PaymentProcessor {
              // Using payment here because i'm working with payments.
              public void process(Payment payment) {
              boolean expired = expirationChecker.check(payment);
              boolean pastLimit = limitChecker.check(payment);

              if (!expired && !pastLimit) {
              acceptPayment(payment);
              }
              }
              }

              class ExpirationChecker {
              // This the `Expirable` world, so i'm using Expirable here
              public boolean check(Expirable expirable) {
              // code
              }
              }

              class LimitChecker {
              // This class is about checking limits, thats why im using `Limited` here
              public boolean check(Limited limited) {
              // code
              }
              }






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered 15 hours ago









              KaNa0011KaNa0011

              469311




              469311













              • LSV? Don't you mean LSP?

                – Peter Mortensen
                10 mins ago



















              • LSV? Don't you mean LSP?

                – Peter Mortensen
                10 mins ago

















              LSV? Don't you mean LSP?

              – Peter Mortensen
              10 mins ago





              LSV? Don't you mean LSP?

              – Peter Mortensen
              10 mins ago











              1














              Usually, many, client-specific interfaces are fine, and somewhat part of the Interface segregation principle (the "I" in SOLID). Some more specific points, on a technical level, have already been mentioned in other answers.



              Particularly that you can go too far with this segregation, by having a class like



              class Person implements FirstNameProvider, LastNameProvider, AgeProvider ... {
              @Override String getFirstName() {...}
              @Override String getLastName() {...}
              @Override int getAge() {...}
              ...
              }


              Or, conversely, that you have an implementing class that is too powerful, as in



              class Application implements DatabaseReader, DataProcessor, UserInteraction, Visualizer {
              ...
              }




              I think that the main point in the Interface Segregation Principle is that the interfaces should be client-specific. They should basically "summarize" the functions that are required by a certain client, for a certain task.



              To put it that way: The issue is to strike the right balance between the extremes that I sketched above. When I'm trying to figure out interfaces and their relationships (mutually, and in terms of the classes that implement them), I always try to take a step back and ask myself, in an intentionally naïve way: Who is going to receive what, and what is he going to do with it?



              Regarding your example: When all your clients always need the functionality of Interface1 and Interface2 at the same time, then you should consider either defining an



              interface Combined extends Interface1, Interface2 { }


              or not have different interfaces in the first place. On the other hand, when the functionalities are completely distinct and unrelated and never used together, then you should wonder why the single class is implementing them at the same time.



              At this point, one could refer to another principle, namely Composition over inheritance. Although it is not classically related to implementing multiple interfaces, composition can also be favorable in this case. For example, you could change your class to not implement the interfaces directly, but only provide instances that implement them:



              class Example {
              Interface1 getInterface1() { ... }
              Interface2 getInterface2() { ... }
              }


              (Note: It looks a bit odd in this Example (sic!), but depending on the complexity of the implementation of Interface1 and Interface2, it can really make sense to keep them separated)






              share|improve this answer
























              • This is the correct answer. The interface is built for the contract that the client code needs fulfilled. If the client code reasonably expects to be able to call someInterface1Method AND someInterface2Method, then that is a new contract. From wikipedia on ISP: "no client should be forced to depend on methods it does not use." and "clients will only have to know about the methods that are of interest to them."

                – Xtros
                6 hours ago


















              1














              Usually, many, client-specific interfaces are fine, and somewhat part of the Interface segregation principle (the "I" in SOLID). Some more specific points, on a technical level, have already been mentioned in other answers.



              Particularly that you can go too far with this segregation, by having a class like



              class Person implements FirstNameProvider, LastNameProvider, AgeProvider ... {
              @Override String getFirstName() {...}
              @Override String getLastName() {...}
              @Override int getAge() {...}
              ...
              }


              Or, conversely, that you have an implementing class that is too powerful, as in



              class Application implements DatabaseReader, DataProcessor, UserInteraction, Visualizer {
              ...
              }




              I think that the main point in the Interface Segregation Principle is that the interfaces should be client-specific. They should basically "summarize" the functions that are required by a certain client, for a certain task.



              To put it that way: The issue is to strike the right balance between the extremes that I sketched above. When I'm trying to figure out interfaces and their relationships (mutually, and in terms of the classes that implement them), I always try to take a step back and ask myself, in an intentionally naïve way: Who is going to receive what, and what is he going to do with it?



              Regarding your example: When all your clients always need the functionality of Interface1 and Interface2 at the same time, then you should consider either defining an



              interface Combined extends Interface1, Interface2 { }


              or not have different interfaces in the first place. On the other hand, when the functionalities are completely distinct and unrelated and never used together, then you should wonder why the single class is implementing them at the same time.



              At this point, one could refer to another principle, namely Composition over inheritance. Although it is not classically related to implementing multiple interfaces, composition can also be favorable in this case. For example, you could change your class to not implement the interfaces directly, but only provide instances that implement them:



              class Example {
              Interface1 getInterface1() { ... }
              Interface2 getInterface2() { ... }
              }


              (Note: It looks a bit odd in this Example (sic!), but depending on the complexity of the implementation of Interface1 and Interface2, it can really make sense to keep them separated)






              share|improve this answer
























              • This is the correct answer. The interface is built for the contract that the client code needs fulfilled. If the client code reasonably expects to be able to call someInterface1Method AND someInterface2Method, then that is a new contract. From wikipedia on ISP: "no client should be forced to depend on methods it does not use." and "clients will only have to know about the methods that are of interest to them."

                – Xtros
                6 hours ago
















              1












              1








              1







              Usually, many, client-specific interfaces are fine, and somewhat part of the Interface segregation principle (the "I" in SOLID). Some more specific points, on a technical level, have already been mentioned in other answers.



              Particularly that you can go too far with this segregation, by having a class like



              class Person implements FirstNameProvider, LastNameProvider, AgeProvider ... {
              @Override String getFirstName() {...}
              @Override String getLastName() {...}
              @Override int getAge() {...}
              ...
              }


              Or, conversely, that you have an implementing class that is too powerful, as in



              class Application implements DatabaseReader, DataProcessor, UserInteraction, Visualizer {
              ...
              }




              I think that the main point in the Interface Segregation Principle is that the interfaces should be client-specific. They should basically "summarize" the functions that are required by a certain client, for a certain task.



              To put it that way: The issue is to strike the right balance between the extremes that I sketched above. When I'm trying to figure out interfaces and their relationships (mutually, and in terms of the classes that implement them), I always try to take a step back and ask myself, in an intentionally naïve way: Who is going to receive what, and what is he going to do with it?



              Regarding your example: When all your clients always need the functionality of Interface1 and Interface2 at the same time, then you should consider either defining an



              interface Combined extends Interface1, Interface2 { }


              or not have different interfaces in the first place. On the other hand, when the functionalities are completely distinct and unrelated and never used together, then you should wonder why the single class is implementing them at the same time.



              At this point, one could refer to another principle, namely Composition over inheritance. Although it is not classically related to implementing multiple interfaces, composition can also be favorable in this case. For example, you could change your class to not implement the interfaces directly, but only provide instances that implement them:



              class Example {
              Interface1 getInterface1() { ... }
              Interface2 getInterface2() { ... }
              }


              (Note: It looks a bit odd in this Example (sic!), but depending on the complexity of the implementation of Interface1 and Interface2, it can really make sense to keep them separated)






              share|improve this answer













              Usually, many, client-specific interfaces are fine, and somewhat part of the Interface segregation principle (the "I" in SOLID). Some more specific points, on a technical level, have already been mentioned in other answers.



              Particularly that you can go too far with this segregation, by having a class like



              class Person implements FirstNameProvider, LastNameProvider, AgeProvider ... {
              @Override String getFirstName() {...}
              @Override String getLastName() {...}
              @Override int getAge() {...}
              ...
              }


              Or, conversely, that you have an implementing class that is too powerful, as in



              class Application implements DatabaseReader, DataProcessor, UserInteraction, Visualizer {
              ...
              }




              I think that the main point in the Interface Segregation Principle is that the interfaces should be client-specific. They should basically "summarize" the functions that are required by a certain client, for a certain task.



              To put it that way: The issue is to strike the right balance between the extremes that I sketched above. When I'm trying to figure out interfaces and their relationships (mutually, and in terms of the classes that implement them), I always try to take a step back and ask myself, in an intentionally naïve way: Who is going to receive what, and what is he going to do with it?



              Regarding your example: When all your clients always need the functionality of Interface1 and Interface2 at the same time, then you should consider either defining an



              interface Combined extends Interface1, Interface2 { }


              or not have different interfaces in the first place. On the other hand, when the functionalities are completely distinct and unrelated and never used together, then you should wonder why the single class is implementing them at the same time.



              At this point, one could refer to another principle, namely Composition over inheritance. Although it is not classically related to implementing multiple interfaces, composition can also be favorable in this case. For example, you could change your class to not implement the interfaces directly, but only provide instances that implement them:



              class Example {
              Interface1 getInterface1() { ... }
              Interface2 getInterface2() { ... }
              }


              (Note: It looks a bit odd in this Example (sic!), but depending on the complexity of the implementation of Interface1 and Interface2, it can really make sense to keep them separated)







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered 12 hours ago









              Marco13Marco13

              42k855108




              42k855108













              • This is the correct answer. The interface is built for the contract that the client code needs fulfilled. If the client code reasonably expects to be able to call someInterface1Method AND someInterface2Method, then that is a new contract. From wikipedia on ISP: "no client should be forced to depend on methods it does not use." and "clients will only have to know about the methods that are of interest to them."

                – Xtros
                6 hours ago





















              • This is the correct answer. The interface is built for the contract that the client code needs fulfilled. If the client code reasonably expects to be able to call someInterface1Method AND someInterface2Method, then that is a new contract. From wikipedia on ISP: "no client should be forced to depend on methods it does not use." and "clients will only have to know about the methods that are of interest to them."

                – Xtros
                6 hours ago



















              This is the correct answer. The interface is built for the contract that the client code needs fulfilled. If the client code reasonably expects to be able to call someInterface1Method AND someInterface2Method, then that is a new contract. From wikipedia on ISP: "no client should be forced to depend on methods it does not use." and "clients will only have to know about the methods that are of interest to them."

              – Xtros
              6 hours ago







              This is the correct answer. The interface is built for the contract that the client code needs fulfilled. If the client code reasonably expects to be able to call someInterface1Method AND someInterface2Method, then that is a new contract. From wikipedia on ISP: "no client should be forced to depend on methods it does not use." and "clients will only have to know about the methods that are of interest to them."

              – Xtros
              6 hours ago













              0














              The problem you describe often comes about through over-zealous application of the Interface Segregation Principle, encouraged by languages' inability to specify that members of one interface should, by default, be chained to static methods which could implement sensible behaviors.



              Consider, for example, a basic sequence/enumeration interface and the following behaviors:




              1. Produce an enumerator which can read out the objects if no other iterator has yet been created.


              2. Produce an enumerator which can read out the objects even if another iterator has already been created and used.


              3. Report how many items are in the sequence


              4. Report the value of the Nth item in the sequence


              5. Copy a range of items from the object into an array of that type.


              6. Yield a reference to an immutable object that can accommodate the above operations efficiently with contents that are guaranteed never to change.



              I would suggest that such abilities should be part of the basic sequence/enumeration interface, along with a method/property to indicate which of the above operations are meaningfully supported. Some kinds of single-shot on-demand enumerators (e.g. an infinite truly-random sequence generator) might not be able to support any of those functions, but segregating such functions into separate interfaces will make it much harder to produce efficient wrappers for many kinds of operations.



              One could produce a wrapper class that would accommodate all of the above operations, though not necessarily efficiently, on any finite sequence which supports the first ability. If, however, the class is being used to wrap an object that already supports some of those abilities (e.g. access the Nth item), having the wrapper use the underlying behaviors could be much more efficient than having it do everything via the second function above (e.g. creating a new enumerator, and using that to iteratively read and ignore items from the sequence until the desired one is reached).



              Having all objects that produce any kind of sequence support an interface that includes all of the above, along with an indication of what abilities are supported, would be cleaner than trying to have different interfaces for different subsets of abilities, and requiring that wrapper classes make explicit provision for any combinations they want to expose to their clients.






              share|improve this answer




























                0














                The problem you describe often comes about through over-zealous application of the Interface Segregation Principle, encouraged by languages' inability to specify that members of one interface should, by default, be chained to static methods which could implement sensible behaviors.



                Consider, for example, a basic sequence/enumeration interface and the following behaviors:




                1. Produce an enumerator which can read out the objects if no other iterator has yet been created.


                2. Produce an enumerator which can read out the objects even if another iterator has already been created and used.


                3. Report how many items are in the sequence


                4. Report the value of the Nth item in the sequence


                5. Copy a range of items from the object into an array of that type.


                6. Yield a reference to an immutable object that can accommodate the above operations efficiently with contents that are guaranteed never to change.



                I would suggest that such abilities should be part of the basic sequence/enumeration interface, along with a method/property to indicate which of the above operations are meaningfully supported. Some kinds of single-shot on-demand enumerators (e.g. an infinite truly-random sequence generator) might not be able to support any of those functions, but segregating such functions into separate interfaces will make it much harder to produce efficient wrappers for many kinds of operations.



                One could produce a wrapper class that would accommodate all of the above operations, though not necessarily efficiently, on any finite sequence which supports the first ability. If, however, the class is being used to wrap an object that already supports some of those abilities (e.g. access the Nth item), having the wrapper use the underlying behaviors could be much more efficient than having it do everything via the second function above (e.g. creating a new enumerator, and using that to iteratively read and ignore items from the sequence until the desired one is reached).



                Having all objects that produce any kind of sequence support an interface that includes all of the above, along with an indication of what abilities are supported, would be cleaner than trying to have different interfaces for different subsets of abilities, and requiring that wrapper classes make explicit provision for any combinations they want to expose to their clients.






                share|improve this answer


























                  0












                  0








                  0







                  The problem you describe often comes about through over-zealous application of the Interface Segregation Principle, encouraged by languages' inability to specify that members of one interface should, by default, be chained to static methods which could implement sensible behaviors.



                  Consider, for example, a basic sequence/enumeration interface and the following behaviors:




                  1. Produce an enumerator which can read out the objects if no other iterator has yet been created.


                  2. Produce an enumerator which can read out the objects even if another iterator has already been created and used.


                  3. Report how many items are in the sequence


                  4. Report the value of the Nth item in the sequence


                  5. Copy a range of items from the object into an array of that type.


                  6. Yield a reference to an immutable object that can accommodate the above operations efficiently with contents that are guaranteed never to change.



                  I would suggest that such abilities should be part of the basic sequence/enumeration interface, along with a method/property to indicate which of the above operations are meaningfully supported. Some kinds of single-shot on-demand enumerators (e.g. an infinite truly-random sequence generator) might not be able to support any of those functions, but segregating such functions into separate interfaces will make it much harder to produce efficient wrappers for many kinds of operations.



                  One could produce a wrapper class that would accommodate all of the above operations, though not necessarily efficiently, on any finite sequence which supports the first ability. If, however, the class is being used to wrap an object that already supports some of those abilities (e.g. access the Nth item), having the wrapper use the underlying behaviors could be much more efficient than having it do everything via the second function above (e.g. creating a new enumerator, and using that to iteratively read and ignore items from the sequence until the desired one is reached).



                  Having all objects that produce any kind of sequence support an interface that includes all of the above, along with an indication of what abilities are supported, would be cleaner than trying to have different interfaces for different subsets of abilities, and requiring that wrapper classes make explicit provision for any combinations they want to expose to their clients.






                  share|improve this answer













                  The problem you describe often comes about through over-zealous application of the Interface Segregation Principle, encouraged by languages' inability to specify that members of one interface should, by default, be chained to static methods which could implement sensible behaviors.



                  Consider, for example, a basic sequence/enumeration interface and the following behaviors:




                  1. Produce an enumerator which can read out the objects if no other iterator has yet been created.


                  2. Produce an enumerator which can read out the objects even if another iterator has already been created and used.


                  3. Report how many items are in the sequence


                  4. Report the value of the Nth item in the sequence


                  5. Copy a range of items from the object into an array of that type.


                  6. Yield a reference to an immutable object that can accommodate the above operations efficiently with contents that are guaranteed never to change.



                  I would suggest that such abilities should be part of the basic sequence/enumeration interface, along with a method/property to indicate which of the above operations are meaningfully supported. Some kinds of single-shot on-demand enumerators (e.g. an infinite truly-random sequence generator) might not be able to support any of those functions, but segregating such functions into separate interfaces will make it much harder to produce efficient wrappers for many kinds of operations.



                  One could produce a wrapper class that would accommodate all of the above operations, though not necessarily efficiently, on any finite sequence which supports the first ability. If, however, the class is being used to wrap an object that already supports some of those abilities (e.g. access the Nth item), having the wrapper use the underlying behaviors could be much more efficient than having it do everything via the second function above (e.g. creating a new enumerator, and using that to iteratively read and ignore items from the sequence until the desired one is reached).



                  Having all objects that produce any kind of sequence support an interface that includes all of the above, along with an indication of what abilities are supported, would be cleaner than trying to have different interfaces for different subsets of abilities, and requiring that wrapper classes make explicit provision for any combinations they want to expose to their clients.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered 11 hours ago









                  supercatsupercat

                  56.5k2117150




                  56.5k2117150






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54184354%2fhow-do-i-avoid-breaking-the-liskov-substitution-principle-with-a-class-that-impl%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      數位音樂下載

                      格利澤436b

                      When can things happen in Etherscan, such as the picture below?