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.