Search code examples
javadesign-patternsdesign-principles

Add methods to classes without breaking implementations


Let say I have 2 classes called class Cow ad class Pig.

They both implements interface Animal.

For the interface there are only 2 methods called public void eat() and public void speak().

All is fine. But while this seems good making use of interfaces, I thought that if I ever needed to add method(s) to this interface, implementation would break, namely I would need to go implement the new methods in these classes, which breaks the "close-open principle".

So I thought of, in addition to interface, I would make use of abstract class as well, should it be needed that I needed to add new method(s) in the future.

So, for example, public class Cow extends ... implements Animal.

It sounds like a good plan (if it is not, please correct me).

But the problem is, what if these classes extend already some other class? In such case, I could not extend 2 classes.

So my question is:

Is there a pattern where I could declare a common interface of related classes while withholding the ability to add new methods in the future that doesn't break the "closed-open principle" and doesn't break implementations?


Solution

  • With Java 8 there are default methods

    public interface Animal {
    
        void eat();
        void speak();
        default void sleep(){}
    
    }
    

    Now your Animal must override eat and speak but may choose to override sleep.

    Pre Java 8 using a abstract class was the usual way to protect against having to implement every interface method. As you noted, this doesn't work with multiple inheritance so cannot be used to solve all cases.

    P.S. don't declare interface methods public, this is the default visibility for all interface members.