If you absolutely have to use the same name for the function, and add new behavior, then you have several options. A special device invented for this sort of situations is called Villegas-Gayley technique. In this particular case, it will look like
ClearAll[foo,inFoo]; foo[n_] := 2*n - 1; foo[x_] /; ! TrueQ[inFoo] := Block[{inFoo = True}, foo[x] + 1]
where the last definition is the one which alters the behavior. You can test:
foo /@ {1, 2} (* {2, 4} *)
However, this won't always work. For example, this won't work if your function has been defined specifically on these values:
ClearAll[foo]; foo[1] = 1; foo[2] = 3;
Adding this definition now
foo[x_] /; ! TrueQ[inFoo] := Block[{inFoo = True}, foo[x] + 1]
won't help:
foo /@ {1, 2} (* {1, 3} *)
The reasons for that have to do with the relative specificity of various patterns, and the fact that a function defined on specific values has a different (hash-table - based) representation which is hard to override.
In this case, I suggest to use a rather heavy-handed approach I described here. Using functions from it, we have:
withUserDefs[ foo, {foo[x_] /; ! TrueQ[inFoo] := Block[{inFoo = True}, foo[x] + 1]}, foo /@ {1, 2} ] (* {2, 4} *)
However, best would be to reconsider your design and needs, since chances are that you don't really need any of these methods, and can find a solution by more traditional means.
foo2[x_] = foo[x] + 1? $\endgroup$