views:

142

answers:

3

I have a parent class with several children. One of the children, has one overridden method that, for its particular internal usage, needs one more parameter. I don't want to change the method's signature because the overridden method in the other children does not need this parameter, also, I don't want to add a class property because it is pointless in this case.

How do you deal with these situations?

So far I've added a NotImplementedException in the method and created a new one, but it really is something I've done while I wait for an answer, I don't want to do it this way.


Edit after Jon Skeet's answer

I'll try to figure out if I've understood what Jon suggested. This is quite interesting.

public abstract class Parent {
    public abstract void aMethod(Object parameter);
}

public class NotReallyParentChild {
    public Parent createInstance(){
        return new Child();
    }
}

public abstract class Child extends Parent {

}

Mmmmh no I'm completely wrong here, I don't understand the second part of your post, could you please shed some light on this?

+8  A: 

It sounds like you don't really have a proper inheritance relationship there - it breaks Liskov's Subtitutability Principle, because you can't use this "child" as if it were an instance of the parent, without extra knowledge.

How about making the "child" class not derive from the "parent", but provide a method on the child which will create an instance of some subclass of the parent, which "knows" the appropriate extra bit of information? If you could give us more information about what the classes are doing, we could give more concrete examples of what the code might look like.

EDIT: It's really hard to try to make this much clearer without knowing more about what you're doing, but something like:

public class NotReallyParentChild {
    public Parent createInstance(Object extraParameter){
        return new ChildWithParameter(extraParameter);
    }
}

That ChildWithParameter class could then override the appropriate method without taking any extra information, because it already had it as part of its own internal state.

Jon Skeet
+1 - if it needs an extra parameter, it's **not overriding the same method**.
Andrzej Doyle
I've edited my question, what the classes are doing is not that important, I'm more interested on how to address this kind of problem in general (btw the problem was generated by a mistake, I had the information I wanted in a protected object in the parent)
Alberto Zaccagni
Could you explain what you've said in your second paragraph? Feel free to edit the code in my question...
Alberto Zaccagni
Ok thank you Jon, got it now :P
Alberto Zaccagni
+4  A: 

Whilst agreeing with Jon's view that the inheritance model is broken, you can handle scenarios like this by using special parameter objects. That is, instead of having a method:

void myMethod(Object param1, Object param2, Object param3...);

you have an object ParameterObject which contains the parameters required, and your method looks like:

void myMethod(ParameterObject param);

That way, you can add parameters to the parameter object, and not affect or change the interface and implemented methods.

If I'm writing a method and the number of parameters seems excessive, and I believe my encapsulation is not broken in any way (this happens a lot in financial software when equations/models take a lot of inputs), then I find the above a very useful pattern.

Brian Agnew
A: 

You can even further extend the idea of a ParameterObject (as proposed by Brian Agnew) by using generics.

public interface Algorithm<P extends AlgorithmParameter> {
    public void doSomething(P parameters);
}

This way your CoolAlgorithm takes a CoolAlgorithmParameter and your NiceAlgorithm takes a NiceAlgorithmParameter so you don’t have to worry about the parameter object actually being what you want—generics will take care of that.

Bombe
This solution seems to defeat polymorphism as a reference to the base type cannot call your cool algorithm without knowing which type of parameter to pass.
rsp
Polymorphism is sure limited by this—on the other hand, why would you hand algorithm A parameters that are only suited for algorithm B?
Bombe