I am writing a class Baz<T>
with function declarations similar to the following:
public SomeClass1<T> foo(T); // Overload #1
public SomeClass1<T> foo(T, SomeClass1<T>); // Overload #2
public SomeClass1<T> foo(T, SomeClass1<T>, SomeClass1<T>); // Overload #3
Since #1 is the only function that uses this
, I could make all the others static
:
public SomeClass1<T> foo(T);
public static <T> SomeClass1<T> foo(T, SomeClass1<T>); //#2 and #3 now static
public static <T> SomeClass1<T> foo(T, SomeClass1<T>, SomeClass1<T>);
However, that would make calling different foo
overloads inconsistent. I could simply make #1 take a Baz
(instead of this
), but it seems that:
baz.foo(t);
is more syntactic sugar than:
Baz.foo(baz, t);
If I don't make #2 and #3 static, then there is no way to prevent something like:
Baz<Bar> baz1 = new Baz<Bar>(); // Bar is any class type; replaces T
Baz<Bar> baz2 = new Baz<Bar>();
SomeClass1<Bar> sc = new SomeClass1<Bar>(baz1); // make a SomeClass1 that is somehow attached to baz1; however, SomeClass1 does NOT keep a reference to baz1
baz2.foo(new Bar(), sc); // runs and compiles just fine!
What I ended up trying to do was to have a non-static and a static overload for each one, where the non-static overloads simply delegate to the static:
public SomeClass1<T> foo(T); // All non-static overloads delegate to the corresponding static overload
public SomeClass1<T> foo(T, SomeClass1<T>);
public SomeClass1<T> foo(T, SomeClass1<T>, SomeClass1<T>);
public static <T> SomeClass1<T> foo(T, Baz<T>); // Baz could be first or last argument
public static <T> SomeClass1<T> foo(T, SomeClass1<T>);
public static <T> SomeClass1<T> foo(T, SomeClass1<T>, SomeClass1<T>);
I get the following error coming from the declaration of overload #2, #3, and their corresponding static overloads, replacing my-method-signature
with the corresponding method signature and my-class-name
with Baz<T>
, or the data type I am using:
Erasure of method my-method-signature is the same as another method in type my-class-name
Questions:
SomeClass1<T>
and this
objects) even worth it?P.S. Sorry for the long post.
Yes, there is a better option: Do nothing.
There is nothing wrong with having a method that doesn’t need this
to do its job. That’s an implementation choice, which has nothing to do with an instance fulfilling its contract of implementing methods.
There are plenty of commonly used design patterns that have such methods. Take the various factory patterns for example - their methods have a contract to return an instance. Nobody knows or cares if they use this
to get the job done or not.