Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #26769

Re: can this be done with generics?

From Daniel Pitts <newsgroup.nospam@virtualinfinity.net>
Newsgroups comp.lang.java.programmer
Subject Re: can this be done with generics?
References <slrnl9580s.42s.avl@gamma.logic.tuwien.ac.at>
Message-ID <pyIou.381562$5W.329013@fx11.iad> (permalink)
Date 2013-12-07 09:04 -0800

Show all headers | View raw


On 11/24/13 4:55 PM, Andreas Leitgeb wrote:
> I'd like to use the "call methods in a chain" pattern
> across a class-subhierarchy, with most of the methods
> defined in the base-class.
>
> Suppose, I had two classes:
>
>   class Foo {
>      public Foo foo1() {
>         /* do something very interesting ... */
>         return this;
>      }
>      // assume there were like 100 such foo#() methods here
>      //  (in practice they of course have more diverse names)
>   }
>   class Bar extends Foo {
>      public Bar bar() {
>         /* do something very interesting */
>         return this;
>      }
>   }
>
> And then, somewhere else:
>
>    // the single-class chain works just fine:
>    new Foo().foo1().foo42().foo84();
>
>    // but if I start with a Bar, and eventually after some foo#() calls
>    // want to call method bar() which is not in Foo, then I'm out of luck:
>    new Bar().foo1().foo42().foo84().bar(); // doesn't work, of course!
>
> Is there a way to use *generics* for the methods of class Foo such that
> each foo#() returns the *static* type on which the compiler saw it
> applied?
>
> Alternatives, that do NOT satisfy me:
>    a) use an explicit cast to (Bar)
>        ((Bar)(new Bar().foo1().foo42().foo84())).bar();
>       Would turn into a nightmare, when more of Bar's
>       methods got mixed into the chain.
>    b) override each of the 100 foo#()s in Bar with a Bar return-type.
>       Would turn into a nightmare, when more sub-classes like Bar
>       appeared, or new methods added to Foo.
>       (Note, that "bad performance" due to extra calls is NOT my concern here)
>    c) add "Foo bar() { return this; }" in Foo.
>       Would turn into a nightmare, when more sub-classes like Bar
>       appeared (and Foo would have to reflect all subclasses' methods),
>       or some chain accidentally called a subclass method on a chain
>       started from some other class's instance, and compiler wouldn't
>       detect the mistake.
>
> I'm pretty sure, that this would be principially possible (as in: the
> compiler has all the information that would be needed), but I can't seem
> to find an approach for how to capture the static type of the expression
> on which the (non-static) method is called.
>
> Thanks in advance!
>

Yes, this *can* be done with generics, but its relatively ugly and hard 
to maintain.  I've been doing a lot of work in PHP lately, and they have 
a return type hint "@return $this", which makes my IDE of choice 
recognize the intent.  Java, though superior in many ways, is lacking 
that kind of ability.


To answer your question though:

abstract class Foo<T extends Foo<T>> {

     public T foo1() { return getThis(); }

     protected abstract T getThis();

}

class Bar extends Foo<Bar> {

    public Bar bar1() { /* something interesting */ return this; }
    protected T getThis() { return this; }
}



It gets uglier if you need multiple levels of inheritance, or if you 
have two classes which refer to each other.

Back to comp.lang.java.programmer | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

can this be done with generics? Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2013-11-25 00:55 +0000
  Re: can this be done with generics? Arne Vajhøj <arne@vajhoej.dk> - 2013-11-24 21:11 -0500
    Re: can this be done with generics? Saxo <jeti789@web.de> - 2013-11-25 01:43 -0800
      Re: can this be done with generics? Saxo <jeti789@web.de> - 2013-11-25 01:47 -0800
      Re: can this be done with generics? Arne Vajhøj <arne@vajhoej.dk> - 2013-11-26 21:32 -0500
    Re: can this be done with generics? Silvio <silvio@internet.com> - 2013-11-25 11:30 +0100
      Re: can this be done with generics? Saxo <jeti789@web.de> - 2013-11-25 02:36 -0800
      Re: can this be done with generics? Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2013-11-25 10:45 +0000
      Re: can this be done with generics? Arne Vajhøj <arne@vajhoej.dk> - 2013-11-26 21:35 -0500
        Re: can this be done with generics? Silvio <silvio@internet.com> - 2013-11-27 10:48 +0100
        Re: can this be done with generics? Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2013-11-27 10:18 +0000
  Re: can this be done with generics? Patrick Roemer <sangamon@netcologne.de> - 2013-11-25 12:59 +0100
    Re: can this be done with generics? Robert Klemme <shortcutter@googlemail.com> - 2013-11-25 22:31 +0100
      Re: can this be done with generics? Patrick Roemer <sangamon@netcologne.de> - 2013-11-26 12:03 +0100
      Re: can this be done with generics? v_borchert@despammed.com (Volker Borchert) - 2013-11-26 21:32 +0000
        Re: can this be done with generics? Robert Klemme <shortcutter@googlemail.com> - 2013-11-26 23:30 +0100
      Re: can this be done with generics? Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2013-11-27 18:53 +0000
        Re: can this be done with generics? Sebastian <news@seyweiler.dyndns.org> - 2013-11-28 22:28 +0100
          Re: can this be done with generics? Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2013-11-30 14:21 +0000
  Re: can this be done with generics? Mike Amling <mamling@chaff.us> - 2013-11-25 09:02 -0600
    Re: can this be done with generics? Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2013-11-26 01:04 +0000
      Re: can this be done with generics? Robert Klemme <shortcutter@googlemail.com> - 2013-11-26 08:16 +0100
        Re: can this be done with generics? Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2013-11-26 20:42 +0000
    Re: can this be done with generics? Arne Vajhøj <arne@vajhoej.dk> - 2013-11-26 21:38 -0500
      Re: can this be done with generics? Mike Amling <mamling@chaff.us> - 2013-11-27 11:05 -0600
  Re: can this be done with generics? taqmcg@gmail.com - 2013-11-25 08:36 -0800
    Re: can this be done with generics? taqmcg@gmail.com - 2013-11-25 09:04 -0800
      Re: can this be done with generics? Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2013-11-26 00:50 +0000
        Re: can this be done with generics? Arivald <NOSPAMarivald@interia.pl> - 2013-11-26 07:10 +0100
          Re: can this be done with generics? Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2013-11-27 18:58 +0000
  Re: can this be done with generics? Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2013-12-07 09:04 -0800
    Re: can this be done with generics? Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2013-12-07 19:20 +0000
      Re: can this be done with generics? Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2013-12-10 11:14 -0800

csiph-web