For the rest I'll let the code talk about the issue & a possible solution in more detail:
package com.arjun.misc;
/**
* "Setter chaining". The issue is that it returns the object of the
* type of the class in which the setter is.
* For Inheritance concepts this means if A<--B; then B.a()
* will return A not B (exclude overriding).
* This hardly helps chaining. Using generics to solve the problem
*
* @author Arjun Dhar | www.neurosys.biz
* */
public class GenericChainingSetters {
private static class A<T extends A> {
T setA(String something) {
return (T)this;
}
}
private static class B<T extends B> extends A<T> {
T setB(String something) {
return (T)this;
}
}
private static class C<T extends C> extends B<T> {
T setC(String something) {
return (T)this;
}
}
public static void main(String[] args) {
//WORKS
B<B> b = new B();
b.setA("abc").setB("abc again?!");
//WORKS
C<C> c = new C();
c.setA("abc").setB("abc again?!").setC("Hurray!");
}
}
Only thing is that as with Generics (erasure),
one cant (can but should not logically) do something stupid like:
B<C> b = new B();
Thoughts & suggestions welcome
thanks
-Arjun
Click here to see better way using Java 8
Good stuff, but I think
ReplyDeletec.setA("abc").setB("abc again?!").setC("Hurray!")
should not work. Reasoning this out:
typeOf(c) = C
typeOf(c.setA("abc")) = C
typeOf(c.setA("abc").setB("abc again?!")) = B
B doesn't have a setC method
I wont disagree with that, because the definition of typeOf() is not clear to me. I think its a C operator that may or may not be mathematically correct.
ReplyDeleteStill, lets assume your typeOf(..) analogy is correct.
In my opinion it is also important to question; if the idea of chaining also implies:
Mathematical Commutativity (i.e. A x B x C = C x B x A) => setA().setB().setC() = setA().setC().setB() = setC().setB().setA()
If one denies this for Inheritance, then one must deny this also for the same object (without inheritance).
So I leave this to you.
If you feel that "Commutativity" holds for the same object
=> Then that mathematically & Logically implies, it should hold for inheritance
=> Then that mathematically & Logically implies, that it contradicts the typeOf(...) analogy.
However, if you feel Commutativity should not hold. Then both the school of thought converge to a single answer.
imo Commutativity "should hold" but I cant be too sure. Need to think on this more.
Very interesting.
Each setter changes the state of an object. So should the result of the chain be the same irrespective of the order?