1

I'm trying to figure something out but googling is difficult since I'm not sure exactly what keywords are needed. Suppose I have a class like this:

class MyClass {
    int i = 0;

    public MyClass increment() {
        i++;
        return this;
    }
}

and then I have a subclass:

class MySubClass extends MyClass { }

and then I want do the following:

MySubClass mySubClass2 = new MySubClass().increment();

The problem is that the object returned by increment is recognized as an instance of MyClass and not MySubClass, so this won't work. Is there a way to declare increment in MyClass so that it always returns something of the subclass's type?

theelk801
  • 33
  • 6
  • You could override the `increment` method in your subclass to return an instance of `MySubClass`. – cegredev Apr 14 '20 at 20:27
  • Right, but is there a way to have that happen automatically instead of having to override every time? – theelk801 Apr 14 '20 at 20:28
  • If you want to return `this` from multiple sub-classes, it will always be of their type. What you can do to save some trouble is to declare the base class and `increment()` as abstract. – Tasos P. Apr 14 '20 at 20:35
  • 1
    Does this answer your question? [Method chaining + inheritance don’t play well together?](https://stackoverflow.com/questions/1069528/method-chaining-inheritance-don-t-play-well-together) – Savior Apr 14 '20 at 20:35
  • This is called a "self type" . Java does not have this feature but it's possible to achieve something similar to it with generics. – Joni Apr 14 '20 at 20:37

1 Answers1

0

You can use self-bounded generics:

class MyClass<M extends MyClass<M>> {
    int i = 0;

    public M self() {
      // unchecked cast here, because there is no guarantee that M is the self-type.
      return (M) this;
    }

    public M increment() {
        i++;
        return self();
    }
}

Then, extend the class like:

class MySubClass extends MyClass<MySubClass> { }

It's pretty ugly, though.

Ideone demo

Andy Turner
  • 137,514
  • 11
  • 162
  • 243