简体   繁体   中英

Java - extending class as return type on interface/abstract method

I was trying to find a way to create an interface/abstract method with the declaring/extending class as return type. (eg classA extends interfaceA, and the method should return a ClassA object).

Now I found some post that the compiler wont complain about something like that, but the JVM isn't able to handle such thing, meaning this mechanic just doesn't exist in java.

So I came up with the following idea, from wich I have no idea if it is technically save enough to do. (eg will it cause an loop)

public interface ISomeInterface<T extends ISomeInterface<T>> {
    public T get();
}

meaning you can use it in this way. Although this doesnt force an external user to use the extending class, it at least gives the opportunity to do so if prefered:

public class ExtendingClass implements ISomeInterface<ExtendingClass>{
    @Override
    public ExtendingClass get(){}
}

Now this gives no compiler or runtime error, but I'm concerned if this would create any problems if used extensively.

I would appreciate if someone could confirm that this would or wouldn't cause problems. (any other feedback is welcome as well).

There's nothing wrong with this. It's actually a fairly common practice.

It's a very common practice. Examples include:

Enum<E extends Enum<E>>

BaseStream<T, S extends BaseStream<T, S>>

However, make sure you are aware of the limitations. The main one is that it doesn't work well with inheritance.

For example, if you have an interface

interface Animal<A extends Animal<A>>

you may decide to write a concrete implementation like this

class Duck implements Animal<Duck>

This works fine, but if you later decide you want to extend Duck , you won't be able to write this:

class MallardDuck extends Duck implements Animal<MallardDuck>

The reason you can't do this is that you can't implement the same generic interface with two different type parameters - since Duck already implements Animal<Duck> , it is not possible for MallardDuck to implement Animal<MallardDuck> .

So, make sure that if you use this pattern you think very carefully to begin with how you intend to implement the interface. It works with Enum because the language does not allow you to extend them, but if used too much this pattern can create a total mess.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM