Java Generics question, daisy-chaining object calls

Consider the following code, which I know will not compile:

	class Alpha<T>
	{
		public T DoAlpha()
		{
			return T;
		}
	}
	
	class Beta<T> extends Alpha<T>
	{
		public T DoBeta()
		{
			return T;
		}
	}
	
	class Gamma<T> extends Beta<T>
	{
		public T DoGamma()
		{
			return T;
		}
	}
	
	
	public static void main(String[] args)
	{
		Gamma gamma = new Gamma<Gamma>();
		
		gamma.DoAlpha().DoBeta().DoGamma();
	}

The idea here is to create an inheritance hierarchy such that you can daisy-chain calls like in the main method in any order. I do not even know if this is possible. A co-worker wanted to do something like this and at first I thought it should be quite doable using generics, but then I got stuck.

So, is this possible, and if so, how?

I don’t know if that’s possible in Java. Your code might work with lots of changes (and you have to remember to “return this” on every method, where is a cast to T, but I’m not sure it would work.

For the record, I tend to stay away from Java because I think the language is a mess, so I apologize for not knowing more to help you at this specific case.

The code I provided is illustrative of what I want. I know its wrong and the real solution, if there is one, would probably look considerably different. You can’t return “this” because “this” is of the wrong type. Messing with that kind of thing is where stuff started to fail.

I did go down some road where I tried something like: Alpha<T extends Alpha>
Then things got messy in the next subclass and I never figured out how to return “this” from a method that was supposed to return type T.

This is Groovy, not Java (hence shortcuts for println and scriptiness), but I think it’ll work in straight Java, too.

class Alpha<T>
{
    public T DoAlpha()
    {
        println "alpha"
	return (T) this;
    }
}

class Beta<T> extends Alpha<T>
{
    public T DoBeta()
    {
        println "beta"
	return (T) this;
    }
}

class Gamma<T> extends Beta<T>
{
    public T DoGamma()
    {
        println "gamma"
	return (T) this;
    }
}

Gamma gamma = new Gamma<Gamma>();

gamma.DoAlpha().DoBeta().DoGamma();
gamma.DoBeta().DoAlpha().DoGamma();
gamma.DoGamma().DoBeta().DoAlpha();

Output:

alpha
beta
gamma
beta
alpha
gamma
gamma
beta
alpha

Edit: that said, for the love of God, why? Whatever your co-worker’s goal is, I’m about 99% sure there must be a better way.

He’s emulating something I’ve seen (and used) quite a bit in Smalltalk, which is called “cascading”. There’s something similar in functional languages, though it’s of course implemented in a quite different way.

EDIT: I just remembered that cascading is quite common in Javascript as well.

That will not work in Java. I am beginning to think this is not possible, kind of like some kind of infinite loop of dependencies.

IE: new Alpha<Alpha> // Needs to be
new Alpha<Alpha<Alpha>>  // needs to be
new Alpha<Alpha<Alpha<Alpha>>>> // etc...

See what I mean?

I have no idea why my co-worker wants to do that. I just thought it was an interesting puzzle and was curious on how to do such a thing in Java, if its possible.

There are other ways to try to implement something of the sort (using interfaces, for instance, or using components instead of inheritance), but it will be a ugly hack… like most things in Java.

Interfaces are out, because you do not want to end up making the:
interface GOD { everything under the sun }

Yeah. As I said, there are no elegant ways to do that in Java, at least not that I know of. But keep in mind that the last time I wrote something complex in Java, it didn’t have generics yet.

Cascading is a common pattern in Java, too, but that’s usually a pattern like: builder.setProperty().setProperty().setProperty(). That’s perfectly straightforward, and Android uses it for dialog building, among other things.

The generic typing is the wrinkle here, and the ‘for the love of God why’ part. It works in Groovy (and Smalltalk and Javascript, for that matter) because they aren’t strongly typed in the first place. I’m pretty sure doing it with generics in Java is impossible.

this will fail because all of the “Do” methods return a T - and T is not defined to have a do method. So it won’t nearly compile and it makes no sense.

So gamma.DoAlpha() returns a T, not an alpha/beta or gamma,

EDIT: The generic of a T does not make it a T in any way…it is only associated with T by what you define. I suspect it will fail on the cast in an individual compile of the class because of this.

The way all of this almost but not entirely makes sense to me suggests I should really start studying my Java again before I wrap up this sequence of math courses and get back into programming proper. . .

I have been doing more C# lately than java, so this was quickly genned up in VS2010…so this syntax is slightly different for java, but this would probably achieve what is desired…I hate seeing various Q/A threads where instead of answering the question they ask the question “why would you ever do that?” but looking at it that is my first reaction - so perhaps the goal needs to be reconsidered. But with this technique you can specify which method you want called off of the T class…

public abstract class T
{

    public abstract T doStuff(int theway);

    public const int ALPHA = 0;
    public const int BETA = 1;
    public const int GAMMA = 2;
}

public class Alpha : T
{
    public override T doStuff(int theway)
    {
        if(theway == ALPHA)
        {
            //blah, blah the alpha way
            return this;
        }
        return null;
    }
}

public class Beta : Alpha
{
    public override T doStuff(int theway)
    {
        if(theway == BETA)
        {
            //blah blah the beta way   
            return this;
        }
        return base.doStuff(theway);
    }
}

public class Gamma : Beta
{
    public override T doStuff(int theway)
    {
        if(theway == GAMMA)
        {
            //blah blah the gamma way
            return this;
        }
        return base.doStuff(theway);
    }
}

public class dostuff()
{
    public dostuff()
    {
        Gamma gamma = new Gamma();
        gamma.doStuff(T.GAMMA).doStuff(T.BETA).doStuff(T.ALPHA);
    }
}

That isn’t quite the same thing.
Let me put it this way, Given classes sub1 and sub2.
Sub1 has a unique method that only exists on sub1.
sub2 which extends sub1 also has a unique method.

sub1 can returns its own type in its method, but it doesn’t know about sub2. So if you call sub1.sub1Method() and it returns an instance of sub1, then you can no longer call method sub2Method() even if the actual instance is a sub2 type.

Making sub2 or subN override all previous methods just return its own type is just as bad as creating a god interface that knows about everything.

The more I think about this problem, the less I understand why anyone would really want to do this beyond a pure academic exercise. I am still curious about it though. I am fairly sure that this is not possible in Java.

It is doing structural programing pretending it is OO. I have seen plenty of people do that.

That actually makes things easier to program as there is not abstract base class and no method doStuff to override. - where as class Alpha becomes the base class, and “public Alpha doAlpha” returns a this (no casting).Beta extends alpha and has a new method “public Beta doBeta” which returns a this (again no cast). ditto to doN. Still, when invoked, the programmer knows exactly what he is trying to do (hence - secretly structural). It definitely can be done in Java. No generics needed - just a simple hierarchy.

This was compiled and runs in eclipse (except the line noted):

public class Alpha {

    public Alpha doAlpha()
    {
	//blah blah alpha
	return this;
    }
}
public class Beta extends Alpha{
	public Beta doBeta()
	{
		//blah blah beta
		return this;
	}
}
public class Gamma extends Beta{
	public Gamma doGamma()
	{
	    //blah blah do gamma
	    return this;
	}
}
public class Main 
{
	public static void main(String [] args)
	{
		Gamma gamma = new Gamma();
		gamma.doGamma().doBeta().doAlpha();

            //and there really is no difference programmatically between this and:
            gamma.doGamma();
            gamma.doBeta();
            gamma.doAlpha();

           //so one has to ask if the return type is necessary.
            //casting fun
            Beta wasAGamma = gamma.doBeta();
	    Gamma secretlyGamma = (Gamma)wasAGamma.doBeta();
	    secretlyGamma.doGamma();
	
            Beta notAGamma = new Beta();
	    Gamma nocompileGamma = (Gamma)notAGama;  <-- LINE WILL NOT compile
	
	    List<Alpha> aList = new ArrayList<Alpha>();
	    aList.add(notAGamma);
		
	    try{
		Gamma runtimeExplodingGamma = (Gamma)aList.get(0);
	    }
	    catch(InvalidClassException e)
	    {
		//explosion contained
	    }
           
	}
}

I had suggested casting to him, but he rejected that because it was ugly.
However the quoted line would not work as:
gamma.doAlpha().doBeta().doGamma() without the casts. This the heart of the problem.

On a more philosophical note, lets say this problem is solved. Somehow in java we can have a very large inheritance tree and in the end you could do something like:
sub10.doSub10().doSub1().doSub7().doSub9()...

Is that really a form you would want to use? I think that would become long and ugly especially if you added a bunch of parameters to those calls.

You could format it like
sub10.doSub10()
.doSub1()
.doSub7()
.doSub9()

But if your going to do that, you might as well do it like:
sub10.doSub10();
sub10.doSub1();
sub10.doSub7();

which IMHO is a much better form and wouldn’t require some kind of weird inheritance or generics magic.

Sounds like he wants to create a Fluent Interface

They were pretty popular for awhile, especially in Javascript & C# land but seem to have fallen out of favor.

Thanks, now I know what that is called. He wants a Fluent Interface to work across a class hierarchy in Java.
Now Ill just google that.

I apologize in advance if this isn’t super helpful, but if somebody on my team wanted to do this I would tell them not to. For starters, “inheritance considered harmful” is not too far from the truth. There are a lot of problems with inheritance based designs and typing “java favor…” into google gives “favor composition over inheritance” as the first result. :)

I am a fan of fluent style APIs in general terms, though I think they can also be abused enormously. If you look at the way the Spring Framework does some fluent interfaces they can become very impenetrable and you can end up with one line statements in Spring Security (see 5.2) that look something like

httpSecurity
    .createsANewContext()
        .setSomething()
        .setOther()
    .and()
    .alsoCreateAnotherContext()
         .withThisSetting("foo")
         .etc()

I really don’t like it when they do that.

At any rate, I would really suggest that if the goal is to create a fluent pattern where you take an object and you can perform one or more slightly different operations on it in a fluent manner then the best thing would be to create helper classes that take that object type and act on it in three different ways.

I’ve created a small Java project that does this in a few slightly different ways. The best one in my opinion is the Java 8 functional style where you define Alpha as a Consumer (I’ve created an unnecessary intermediate interface so that if you aren’t using Java 8 you could rework the GreekLetter interface not extend Consumer and instead implement it’s own custom “accept” or “process” method instead of inheriting Consumer.accept())

This ends up looking like this:

	Alpha<String> a = new Alpha<>();
	Beta<String> b = new Beta<>();
	Gamma<String> g = new Gamma<>();

	new GreekAlphabet<String>().addLetter(a).addLetter(b).addLetter(g).accept("Composing");

or

new FluentGreekAlphabet<>("Fluent").applyLetter(a).applyLetter(b).applyLetter(g);

or best yet

a.andThen(b).andThen(g).accept("Consumer");

depending on which approach is used.

Here’s an example of one of the letters:

public class Alpha<T> implements GreekLetter<T> {
	
	@Override
	public void accept(T t) {
		System.out.println("Alpha: " + t.toString());
	}	
	
}

and

@FunctionalInterface
public interface GreekLetter<T> extends Consumer<T> {

}

and

public class FluentGreekAlphabet<T> {

	private T t;

	public FluentGreekAlphabet(T t) {
		this.t = t;
	}
	
	public FluentGreekAlphabet<T> applyLetter(GreekLetter<T> letter) {
		letter.accept(t);
		return this;	
	}
	
	
	
}

and

public class GreekAlphabet<T> implements GreekLetter<T> {
	
	private Set<GreekLetter<T>> letters = new HashSet<GreekLetter<T>>();
	
	public GreekAlphabet<T> addLetter(GreekLetter<T> letter) {
		this.letters.add(letter);
		return this;
	}

	@Override
	public void accept(T t) {
		for(GreekLetter<T> letter : letters) {
			letter.accept(t);
		}
	}	

	
}

[details=Edit: This post is incorrect, it is solvable with just a small modification to the original code.]The reason this will not work out of the box in Java when it works perfectly in Groovy or Javascript is because it Java statically typed, and lacks any kind of “extension methods” like you have in C# or Scala, both of which would enable this type of behaviour.

The choices for doing it in Java is either biting the bullet and having all the parts of the fluent interface is one class, or to represent the composition in the fluent interface itself.

Here’s one way it could be done using Java 8 default methods on interfaces, in order to allow composition without inheritance. You could replace that with the Alpha->Beta->Gamma hierarchy if you prefer that style. That is also probably what you would need to do if the doXXX methods mutate some object state.

interface Builder {
  abstract Alpha alpha();
  abstract Beta beta();
  abstract Gamma gamma();
}

interface Alpha extends Builder {

  default Alpha doAlpha() {
    System.out.println("alpha");
    return this;
  }

}

interface Beta extends Builder {

  default Beta doBeta() {
    System.out.println("beta");
    return this;
  }

}

interface Gamma extends Builder {
  default Gamma doGamma() {
    System.out.println("gamma");
    return this;
  }
}

class Greek implements Alpha, Beta, Gamma {
  @Override
  public Alpha alpha() {
    return this;
  }

  @Override
  public Beta beta() {
    return this;
  }

  @Override
  public Gamma gamma() {
    return this;
  }
}

public class Main {

  public static void main(String[] args) {
    new Greek()
            .alpha()
              .doAlpha()
              .doAlpha()
            .gamma()
              .doGamma()
            .beta()
              .doBeta();

  }
}

[/details]