Why is "extends T" allowed but not "implements T"?

JavaGenericsSyntax

Java Problem Overview


Is there a special reason in Java for using always "extends" rather than "implements" for defining bounds of type parameters?

For example:

public interface C {}
public class A<B implements C>{} 

is prohibited, but

public class A<B extends C>{} 

is correct. What is the reason for that?

Java Solutions


Solution 1 - Java

There is no semantic difference in the generic constraint language between whether a class 'implements' or 'extends'. The constraint possibilities are 'extends' and 'super' - that is, is this class to operate with assignable to that other one (extends), or is this class assignable from that one (super).

Solution 2 - Java

The answer is in here :

>To declare a bounded type parameter, list the type parameter's name, followed by the extends keyword, followed by its upper bound […]. Note that, in this context, extends is used in a general sense to mean either extends (as in classes) or implements (as in interfaces).

So there you have it, it's a bit confusing, and Oracle knows it.

Solution 3 - Java

Probably because for both sides (B and C) only the type is relevant, not the implementation. In your example

public class A<B extends C>{}

B can be an interface as well. "extends" is used to define sub-interfaces as well as sub-classes.

interface IntfSub extends IntfSuper {}
class ClzSub extends ClzSuper {}

I usually think of 'Sub extends Super' as 'Sub is like Super, but with additional capabilities', and 'Clz implements Intf' as 'Clz is a realization of Intf'. In your example, this would match: B is like C, but with additional capabilities. The capabilities are relevant here, not the realization.

Solution 4 - Java

Here is a more involved example of where extends is allowed and possibly what you want:

public class A<T1 extends Comparable<T1>>

Solution 5 - Java

It may be that the base type is a generic parameter, so the actual type may be an interface of a class. Consider:

class MyGen<T, U extends T> {

Also from client code perspective interfaces are almost indistinguishable from classes, whereas for subtype it is important.

Solution 6 - Java

It's sort of arbitrary which of the terms to use. It could have been either way. Perhaps the language designers thought of "extends" as the most fundamental term, and "implements" as the special case for interfaces.

But I think implements would make slightly more sense. I think that communicates more that the parameter types don't have to be in an inheritance relationship, they can be in any kind of subtype relationship.

The Java Glossary expresses a similar view.

Solution 7 - Java

We are used to

class ClassTypeA implements InterfaceTypeA {}
class ClassTypeB extends ClassTypeA {}

and any slight deviation from these rules greatly confuses us.

The syntax of a type bound is defined as

TypeBound:
    extends TypeVariable 
    extends ClassOrInterfaceType {AdditionalBound}

(JLS 12 > 4.4. Type Variables > TypeBound)

If we were to change it, we would surely add the implements case

TypeBound:
    extends TypeVariable 
    extends ClassType {AdditionalBound}
    implements InterfaceType {AdditionalBound}

and end up with two identically processed clauses

ClassOrInterfaceType:
    ClassType 
    InterfaceType

(JLS 12 > 4.3. Reference Types and Values > ClassOrInterfaceType)

except we would also need to take care of implements, which would complicate things further.

I believe it's the main reason why extends ClassOrInterfaceType is used instead of extends ClassType and implements InterfaceType - to keep things simple within the complicated concept. The problem is we don't have the right word to cover both extends and implements and we definitely don't want to introduce one.

<T is ClassTypeA>
<T is InterfaceTypeA>

Although extends brings some mess when it goes along with an interface, it's a broader term and it can be used to describe both cases. Try to tune your mind to the concept of extending a type (not extending a class, not implementing an interface). You restrict a type parameter by another type and it doesn't matter what that type actually is. It only matters that it's its upper bound and it's its supertype.

Solution 8 - Java

Using “extends” in <T extends Comparable> is a promise that the data type will either itself directly implement Comparable, or else will extend a class implementing Comparable. You might have written a subclass B of another class A that implements Comparable, and if you declare your data type <T extends Comparable>, then you may use either A or B as your data type when instantiating the class.

Solution 9 - Java

In fact, when using generic on interface, the keyword is also extends. Here is the code example:

There are 2 classes that implements the Greeting interface:

interface Greeting {
    void sayHello();
}

class Dog implements Greeting {
    @Override
    public void sayHello() {
        System.out.println("Greeting from Dog: Hello ");
    }
}

class Cat implements Greeting {
    @Override
    public void sayHello() {
        System.out.println("Greeting from Cat: Hello ");
    }
}

And the test code:

@Test
public void testGeneric() {
    Collection<? extends Greeting> animals;

    List<Dog> dogs = Arrays.asList(new Dog(), new Dog(), new Dog());
    List<Cat> cats = Arrays.asList(new Cat(), new Cat(), new Cat());

    animals = dogs;
    for(Greeting g: animals) g.sayHello();

    animals = cats;
    for(Greeting g: animals) g.sayHello();
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser120623View Question on Stackoverflow
Solution 1 - JavaTetsujin no OniView Answer on Stackoverflow
Solution 2 - JavaMikaelFView Answer on Stackoverflow
Solution 3 - JavabeetstraView Answer on Stackoverflow
Solution 4 - JavantgView Answer on Stackoverflow
Solution 5 - JavaTom Hawtin - tacklineView Answer on Stackoverflow
Solution 6 - JavaLiiView Answer on Stackoverflow
Solution 7 - JavaAndrew TobilkoView Answer on Stackoverflow
Solution 8 - JavaDavid Hedin-AbreuView Answer on Stackoverflow
Solution 9 - JavazhangdeView Answer on Stackoverflow