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?
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).
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.
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.
Here is a more involved example of where extends is allowed and possibly what you want:
public class A<T1 extends Comparable<T1>>
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.
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.
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.
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();
}
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.
Related
I am trying to understand this recursive interface definition in apache thrift source code
public interface TBase<T extends TBase<?, ?>, F extends TFieldIdEnum> extends Comparable<T>, Serializable {
From my understanding TBase is a interface containing type parameter T and F.
T has the constraint that it also have to be extending TBase that has type parameter containing any type.
What I am confused about is what is the terminating TBase
Say I have
public class TBaseImpl<A, B> implements TBase<A, B>
A has to be a TBase
so there must be another class implement A
public class TBaseImplA<C, D> implements TBase<C, D>
but C have to be a TBase
so there must be another class implement C
This goes on forever.
So my question is
What is terminating condition for TBase
What is the benefit of this recursive definition?
Can someone point me a direction?
Thanks
so there must be another class implement A
That is not necessarily true. With this type of recursive bounds, there are 2 possible ways to satisfy the constraint when creating a subtype.
Declare your own type parameter with the same or more restrictive bounds. This places the burden of choosing the type parameter on the user of this class.
public class TBaseImpl<A extends TBase<A, B>, B extends TFieldIdEnum> implements TBase<A, B>
or more likely
public class TBaseImpl<A extends TBaseImpl<A, B>, B extends TFieldIdEnum> implements TBase<A, B>
Pass the same class as what you're defining to satisfy the original bound.
public class TBaseImpl<B extends TFieldIdEnum> implements TBase<TBaseImpl, B>
A benefit of this pattern is being able to restrict the parameter of a method that is meant to take in another instance of the same class, e.g.:
public void example(T other)
This is (in Java) the Curiously Repeating Template Pattern.
Normally an implementing/overriding method must match the parameter types and order of parameters exactly. But this pattern allows you to narrow the type by narrowing the type parameter. E.g. such a method in TBaseImpl in this case would only take a TBaseImpl and not the broader T or TBase. In such a class there is a relationship between the class and itself.
Another benefit is method chaining, in which a method returns this to allow
obj.method1().method2().method3()
In this way, chaining methods can be declared to return T, so that e.g. a TBase<TBaseImpl> variable can call these methods, each returning a TBaseImpl on which another method can be called.
T method1(); // in TBase
#Override
TBaseImpl method1(); // in TBaseImpl
Incidentally, if you're trying to declare a type variable that is a subtype of an enum, that's not necessary because an enum is final and cannot be extended. It would be simpler to remove F in the interface and have implementing classes use the enum directly.
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?
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).
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.
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.
Here is a more involved example of where extends is allowed and possibly what you want:
public class A<T1 extends Comparable<T1>>
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.
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.
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.
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();
}
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.
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?
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).
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.
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.
Here is a more involved example of where extends is allowed and possibly what you want:
public class A<T1 extends Comparable<T1>>
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.
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.
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.
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();
}
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.
I don't understand why Company compiled. I thought it checked for extends but not for implements?
public interface Employee
public class HourlyEmployee implements Employee
public class Company<T extends Employee>
Company<HourlyEmployee> company = new Company<>();
The extends keyword in Generics has a slightly different semantics than the general extends keyword.
When using extends in the context of Generics, for example T extends Something, this means that T should be a type that either implements the interface Something (in cases when Something is interface), or is a subclass of Something (in case Something is a class).
Probably the reason for this is that if the implements keyword was supported in Generics, this would have made type-parameter declaration too verbose.
For example, you'd have:
<T extends SomeClass implements Serializable & Observable>
Instead, the valid syntax for this would be:
<T extends SomeClass & Serializable & Observable>
And you don't need to have the implements keyword, actually. When defining the bounds of a type T, you just need to point out which types does your type T derive from, without caring if those are interfaces or classes.
The type definition is not a class definition. You can consider type definition as joining few data sets, where the resulting set is your type T.
The notation T extends Employee in the declaration of a type parameter refers to either extending a class or implementing an interface.
public class Company<T implements Employee> is not a valid syntax.
Therefore public class Company<T extends Employee> means that the generic type parameter T of your Company class must implement the Employee interface.
Suppose I have a class
public static class A<T extends D> { ... }
and the class D with two classes extending it: B and C, e.g.
public static class D { ... }
public static class B extends D { ... }
public static class C extends D { ... }
Now, at some place let's say I want an array of A's, irrespective of being of the B-kind or the C-kind. (And apply functions from class D to all items in the array, for example.)
Should I then constrain the type again?
In other words: which of these options is the one to go with?
A<?>[] re;
A<? extends D>[] re;
Which one is best practice?
Since T has an upper bound of D, A<?> is just a shorthand for A<? extends D>. They both mean the same thing - just like if T were unbounded, A<?> would be short for A<? extends Object>.
I don't know of any best practice when it comes to this syntax; I think it's just a matter of coding style. I would prefer A<?> because it's concise, though A<? extends D> immediately communicates the upper bound to a developer unfamiliar with A.
According to me you should go with A<? extends D>[] re;
So that user will not allow you to add only object which extends class D
bounded wildcards provides limited flexibility within bound. Any Type with bounded wildcards can only be instantiated within bound and any instantiation outside bound will result in compiler error.One of the important benefit of using bounded wildcard is that it not only restrict number of Type can be passed to any method as argument it also provides access to methods declared by bound. for example TreeMap(Comparator<? super K> comparator) allows access to compare() method of Comparator in Java.