Por que não há modificador de acesso 'apenas subclasses' em Java?

16

Em Java, existem quatro modificadores de acesso disponíveis para métodos:

public - qualquer classe pode usar esse método.

protected - classes no mesmo pacote e subclasses em qualquer pacote podem usar esse método.

private - somente essa classe pode usar esse método.

no modifier ("pacote privado") - somente classes no mesmo pacote podem usar esse método.

O que acontece com frequência é que eu quero ter métodos úteis em uma superclasse, que todas as subclasses possam usar. Mas não faria sentido para outras classes acessar esse método e, em certo sentido, quebraria o encapsulamento.

Portanto, tenho que declarar esses métodos úteis na superclasse publicou protected, que os expõe a todas as outras classes, pelo menos no pacote. Mesmo que sejam apenas para serem usadas pelas subclasses.

Existe uma razão pela qual não há um subclasses-onlymodificador de acesso em Java? Parece muito estranho para mim. Estou esquecendo de algo?

Além disso, um subclasses-onlymodificador de acesso também seria útil para quando você deseja expor variáveis ​​apenas para subclasses. O que para mim acontece muito.

Aviv Cohn
fonte

Respostas:

10

Como você pode emular o modificador somente de subclasses , use o modificador protegido e imponha que apenas a classe pai e suas subclasses estejam no mesmo pacote.

É de fato uma boa prática, porque os pacotes não apenas ajudam a organizar grandes projetos em termos de coesão, mas também mostram que as classes no mesmo pacote podem ter algum nível de acoplamento.

Tércio de Almeida
fonte
15
"e reforçando que apenas a classe pai e suas subclasses estão no mesmo pacote" - Agora, como alguém faria isso ?!
JimmyB
1
E então você não pode usar o modificador de acesso somente ao pacote. E você precisa de uma quantidade boba de pacotes. Esta não é uma solução prática.
user253751
13

O Java originalmente tinha esse modificador. Foi escrito, private protectedmas removido no Java 1.0.

Suponho que foi um julgamento que a complexidade extra não valia o custo.

Todo recurso de idioma tem um custo: ensiná-lo a novos programadores; na documentação; na implementação nas ferramentas do compilador, JVM e dev; no raciocínio sobre a correção do programa; em restringir a evolução futura da linguagem; e mais. Os recursos de linguagem interagem entre si, potencialmente com as interações de N 2 .

Qual a porcentagem de programadores Java que leram as especificações de linguagem Java e de VM? Aposto que é uma pequena porcentagem, que defende uma linguagem ainda mais simples em prol da compreensibilidade e dos produtos de engenharia dos quais podemos confiar

O benefício do private protectedrecurso foi pequeno, pois o pacote é a principal unidade de modularidade.

Jerry101
fonte
1
então havia uma versão Java antes da 1.0?
Mark Yisri
1
O @MarkYisri Java teve lançamentos públicos alfa e beta em 1995, e um bom código foi escrito contra eles.
David Moles
4

O controle de acesso pode ser pensado como resultado de uma cobertura com um desenvolvedor imaginário que está trabalhando com sua classe sobre os métodos e as propriedades da classe ...

VOCÊ: Diga que quer fazer x, você chama o método doX .. DEV: Me conte mais .. quais são os argumentos?

Isso é público ...

VOCÊ: Dentro do doX eu ligo ... DEV: Uau, muita informação, eu não ligo para isso. Eu só quero saber como usá-lo. Me diga outra coisa.

Isso é privado ...

VOCÊ: Ao subclassificar, tenho doX e doY o que faz .. DEV: Sim, vou subclassificar, me conte mais ...

Isso está protegido ...

VOCÊ: Vou sair de férias em uma hora; ficarei fora pelos próximos 6 meses. O chefe diz que este filhote é seu! Tchau. DEV: Espere, não vá ainda, conte-me tudo ...

Este é o pacote.

VOCÊ: O método doItWhen é chamado apenas por essa classe e não muda em dez anos. DEV: Uau, estamos com menos de 50 minutos. Próxima propriedade e fale mais rápido.

Isso é protegido ...

jmoreno
fonte
3

Isso já existe. Está protegido.

Você tem controle sobre quais classes existem dentro do pacote. Se não houver outra classe no pacote e uma determinada variável ou método estiver protegido, serão 'apenas subclasses'.

Dito isto, mais uma vez, você tem controle sobre quais classes existem dentro do pacote. Você pode optar por não usar os métodos ou variáveis ​​protegidas.


fonte
3
Além de determinados pacotes de sistema reservados, não posso adicionar uma classe a nenhum pacote, mesmo um dos seus que você não pretende adicionar?
David Moles
@ David IIRC sim, mas ele não permitirá que você acesse os campos do pacote de outro JAR; portanto, mesmo que você o coloque no mesmo pacote, se estiver em outro JAR, não será possível acessá-lo. No entanto, se você estiver se referindo ao mesmo JAR, sim, poderá acessá-lo, mas se conseguir modificar o JAR em questão, poderá alterar com facilidade o modificador de acesso.
precisa saber é o seguinte
1
@ Pokechu22 Eu acho que você precisa selar afirmativamente o JAR para obter essa proteção, mas é bom.
David Moles