Let's say I have an interface such as Public Interface CarManager {    Car getCar(String model);}And I have a lot of legacy classes that implement this interface. But now I have a new requirement where I still need to implement this interface, yet the getCar method would now require a new signature such as Public Class fancyNewImpl implements CarManager {    Car getCar(Map<String, Int> modelAndYear) {    // Do something, return something    }}What's the best way to go about this problem, without having to change the method signature of the original interface and all of its implementation classes?I've read a bit on Interface Adapters but I still am not convinced that this would satisfy this particular use case.
Implementing a Legacy Interface's Method but with different signature requirements
object oriented;interfaces
Option 1 - just add new method overload (meaning: a method with same name, but with different signature and technically never considered the same method from the language perspective) to the class that implements the interfaceThis is the answer suggested by Lars.Pros: Least effort.Cons: Only callers which knew the name of your new concrete class fancyNewImpl could perform the downcasting. Furthermore, if the new method signature happens to be also implemented another concrete class, such as fancyNewImplTwo, callers which attempt to downcast to the first concrete class would fail; a caller would have to try both (or, all relevant) concrete classes in order to find the method overload that can use.Option 2 - Define an interface that inherits from the original one, and has the new method overload.https://docs.oracle.com/javase/tutorial/java/IandI/nogrow.htmlpublic interface FancyCarManager extends CarManager{    Car getCar(Map<String, Int> modelAndYear);}Then, implement the two methods in the concrete class that implements the FancyCarManager interface.Callers will still have to do an upcast (technically an interface check) to FancyCarManager and call the new method. But, this option allows multiple concrete classes, such as FancyNewImpl and FancyNewImplTwo, to be callable through the same new method signature, through the new interface.Option 3 - Call the method anyway, without interface, via Java ReflectionBasically this answer deserves to be downvoted just because I mentioned this. But in actual programming workplace, you should see a lot of this happening.(Opinions are mine and are not related to my employer and not inspired from my work. This opinion can be seen in programming blogs elsewhere and articles on the internet.)Option 4 - Abuse the string parameter by encoding things into itFor example, you can concatenate the year into the model string as Car car = carManagerInstance.getCar(model + ; + year);You can add any number of parentheses (as string characters), other punctuations, Unicode characters, or even non-printable characters. You can see where this is going: shovel an XML fragment or a JSON into a string.This will likely choke any existing code that expects the string to be formatted in the old way.However, in legacy code bases where the old meets the new (in a bloody conflicting way), this will happen a lot. This requires a very high testing (quality assurance) effort, and will always have a higher defect rate no matter how much effort is put in.ReminderJust because something is mentioned in this answer does not mean it is proper to use it. Ask your more experienced coworkers for opinions. This is especially valuable if your coworker knows the code base you're working on and your company's coding style.