Danstahr
Danstahr

Reputation: 4319

Java inherited return type

I've got a question about return types in inherited methods in Java. I've got a class and an inherited class. In the inherited class, there's a specific method. It also inherits a method from the parent class that returns instance of itself.

I want something like this class hierarchy:

public class Foo {
    public Foo bar()
    {
        return this;
    }
}

public class FooInherited extends Foo {
    public Whatever baz()
    {
        return new Whatever();
    }
}

My question is if I can call the inherited method from its instance and then call the specific method without overriding the method to return the inherited class or casting the classes explicitly.

Now I want to have a code fragment like this :

FooInherited foo = new FooInherited();
Whatever w = foo.bar().baz();

I feel a difficulty in this, but I'm not very sure if Java has any time saving mechanism for programmers in such situations.

Upvotes: 6

Views: 7385

Answers (3)

Cephalopod
Cephalopod

Reputation: 15145

You can use generics, but it gets ugly quickly.

class Base<This extends Base<This>> {

    public This myself() {
        return (This) this;
    }

}

class Sub<This extends Sub<This>> extends Base<This> {

    public void subOnly() {}

}

{
    Sub<?> sub = new Sub<>();
    sub.myself().subOnly();
    Base<?> base = sub;
    // base.myself().subOnly(); // compile error
}

The alternative is to override the method explicitly:

class Base {

    public Base myself() {
        return this;
    }

}

class Sub extends Base {

    @Override
    public Sub myself() {
        return this; // or return (Sub) super.myself();
    }

    public void subOnly() {}

}

{
    Sub sub = new Sub();
    sub.myself().subOnly();
    Base base = sub;
    // base.myself().subOnly(); // compile error
}

Upvotes: 5

cyon
cyon

Reputation: 9548

Unless you override the method in the subclass you will have to cast:

FooInherited foo = new FooInherited();
Whatever w = ((FooInherited)foo.bar()).baz();

However, due to covariant return types in java you can override it like this:

public class FooInherited extends Foo {


        @Override
        public FooInherited bar()
        {
            return this;
        }
 ...
 }

After overriding you no longer have to cast because the static type of foo is FooInherited:

FooInherited foo = new FooInherited();
Whatever w = foo.bar().baz();

Upvotes: 4

Juvanis
Juvanis

Reputation: 25950

foo.bar() returns a Foo instance and it has no method named as baz(), so it is not possible to compile this statement: Whatever w = foo.bar().baz();

Upvotes: 1

Related Questions