Genéricos de Java – por que “estende T” é permitido, mas não “implementa T”?

Gostaria de saber se existe uma razão especial em Java para usar sempre ” extends ” em vez de ” implements ” para definir limites de typeparameters.

Exemplo:

 public interface C {} public class A{} 

é proibido, mas

 public class A{} 

está correto. Qual é a razão para isso?

Não há diferença semântica na linguagem de restrição genérica entre se uma class “implementa” ou “se estende”. As possibilidades de restrição são ‘extends’ e ‘super’ – isto é, esta class opera com atribuível a essa outra (estende-se), ou é esta class atribuível daquela (super).

A resposta está aqui :

Para declarar um parâmetro de tipo limitado, liste o nome do parâmetro de tipo, seguido pela palavra-chave extends , seguido por seu limite superior […]. Note que, neste contexto, extends é usado em um sentido geral para significar extends (como em classs) ou implements (como em interfaces).

Então, você tem isso, é um pouco confuso, e a Oracle sabe disso.

Provavelmente porque para ambos os lados (B e C) apenas o tipo é relevante, não a implementação. No seu exemplo

 public class A{} 

B também pode ser uma interface. “extends” é usado para definir subinterfaces e subclasss.

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

Eu costumo pensar em ‘Sub estende Super’ como ‘ Sub é como Super , mas com resources adicionais’, e ‘Clz implementa Intf’ como ‘ Clz é uma realização do Intf ‘. No seu exemplo, isso corresponderia: B é como C , mas com resources adicionais. As capacidades são relevantes aqui, não a realização.

Pode ser que o tipo base seja um parâmetro genérico, portanto, o tipo real pode ser uma interface de uma class. Considerar:

 class MyGen { 

Também de interfaces de perspectiva de código de cliente são quase indistinguíveis de classs, enquanto que para subtipo é importante.

Aqui está um exemplo mais envolvido de onde as extensões são permitidas e possivelmente o que você deseja:

public class A>

É meio arbitrário qual dos termos usar. Poderia ter sido de qualquer maneira. Talvez os projetistas de linguagem pensassem em “estender” como o termo mais fundamental e “implementa” como o caso especial das interfaces.

Mas acho que os implements fariam um pouco mais de sentido. Eu acho que comunica mais que os tipos de parâmetro não precisam estar em um relacionamento de inheritance, eles podem estar em qualquer tipo de relação de subtipo.

O Java Glossary expressa uma visão semelhante .

Porque interfaces são apenas classs, exceto que elas não possuem atributos ou implementações. O único uso da palavra-chave “implementa” é permitir que uma class herde múltiplas interfaces, mas não várias classs, e podemos vê-la no código. Eu não sei se eles vão especificar isso no futuro, mas isso não é uma obrigação.