1

I have just come across a piece of code which does:

public interface MyInterface<T extends MyInterface<T>> {...}

Then classes seem to do:

public final class MyClass implements MyInterface<MyClass> {...}

The interface has no definitions, only method declarations. I think extends MyInterface<T> is redundant and the interface can be just:

public interface MyInterface<T> {...}

Being new to Java, is there any purpose of the original interface definition (with the extends part)? Is this a pattern?

s5s
  • 11,159
  • 21
  • 74
  • 121
  • 2
    Possible duplicate of [Java Enum definition](https://stackoverflow.com/questions/211143/java-enum-definition) – ultrajohn Jun 01 '18 at 10:44

1 Answers1

1

The interface has no definitions, only method declarations. I think extends MyInterface is redundant...

No it's not. The bound ensures that only Classes are accepted that implement this interface as well. Let's take a look at an interface:

SomeInterface.java

public interface SomeInterface<T extends SomeInterface<T>>
{
  public T getInterfaceImpl();

  public void setTitle(String text);
}

and two differnet implementing classes:

SomeInterfaceImpl.java:

public class SomeInterfaceImpl implements SomeInterface<SomeInterfaceImpl>
{
  private String title;    

  @Override
  public SomeInterfaceImpl getInterfaceImpl()
  {
    return new SomeInterfaceImpl();
  }

  @Override
  public void setTitle( String text )
  {
    this.title = text;
  }
}

and AnotherSomeInterfaceImpl.java:

public class AnotherSomeInterfaceImpl implements SomeInterface<SomeInterfaceImpl>
{
  private String title;

  @Override
  public SomeInterfaceImpl getInterfaceImpl()
  {
    return new SomeInterfaceImpl();
  }

  @Override
  public void setTitle( String text )
  {
    this.title = text;
  }
}

Take a precise look at the method signature in both implementations. Both classes extend the same interface with the same type parameter which defines the signature of the methods in the same way. Imagine omitting the bound in the interface delcaration. Suddenly an implementing class could look like this:

public class AnotherSomeInterfaceImpl implements SomeInterface<String>
{

  private String title;

  @Override
  public String getInterfaceImpl()
  {
    return "Hello World";
  }

  @Override
  public void setTitle( String text )
  {
    this.title = text;
  }
}

And now we are no longer assured that the returned object of public T getInterfaceImpl() is an implementation of SomeInterface or that it has methods like public void setTitle(String text).

L.Spillner
  • 1,772
  • 10
  • 19