Tenho uma pergunta para a qual não encontrei uma resposta, exceto a seguinte resposta que não atende aos meus requisitos:
"Porque James Gosling não queria"
Eu sei que o Java pode ter interfaces (apenas funções virtuais puras, sem atributos), mas não é exatamente a mesma coisa que as definições de classe.
Respostas:
Essa é a resposta certa, no entanto. A equipe de design de idiomas (Gosling, Sheridan, Naughton, mais tarde Bill Joy, Ken Arnold etc.) decidiu que os cabeçalhos causavam mais problemas do que resolviam . Então eles os projetaram e demonstraram que poderiam criar uma linguagem perfeitamente útil sem a necessidade deles.
Da seção 2.2.1 do white paper Java Language Environment :
Definições redundantes, mantendo arquivos sincronizados, definições conflitantes, definições ocultas - nada disso ocorre em Java, porque você não possui cabeçalhos. Se você deseja ver uma definição de classe simples, pode gerá-la diretamente de um arquivo .java - por exemplo, a maioria dos IDEs mostrará a estrutura de uma classe em uma barra lateral, o que equivale à mesma coisa.
fonte
Não há necessidade real no C ++ de ter as definições e declarações de classe em arquivos separados. Significa apenas que você poderia, pelo menos nos dias C, fazer a análise em uma única varredura na parte superior e inferior do código. Em máquinas sem armazenamento de acesso aleatório, isso era muito importante!
Ter cabeçalhos também permitiu publicar a interface na sua biblioteca de códigos fornecendo o cabeçalho sem a necessidade de revelar o código-fonte. Infelizmente, em C ++, você também precisa revelar os membros de dados privados, o que levou a soluções como o horror do pimpl .
Houve tentativas de criar um ambiente C ++ em que tudo era armazenado em uma estrutura de tipo de banco de dados e não havia arquivos, mas ele não entendeu.
fonte
Por causa do princípio DRY . Em Java, as informações necessárias para usar classes em um pacote (ou classe) estão contidas no arquivo .class. Criar arquivos de cabeçalho separados que contenham as mesmas informações envolveria a repetição em dois lugares.
fonte
Em todos os idiomas - há dois estágios para a criação do código binário final - compilação e vinculação (é claro, há carregamento, mas isso não tem muito impacto aqui). No momento da compilação, é necessário colocar os ganchos (a especificação das funções que serão chamadas) no local apropriado. O Linker realmente os une quando o código real está disponível. Até o momento, não há diferença entre C ++ e Java.
Não é , no entanto, a necessidade de C ++ para ter declaração e definição separada. Se você mantiver a implementação no cabeçalho e se o arquivo do cabeçalho for alterado, o código vinculado a ele precisará ser recompilado. Onde como se a definição estivesse em um arquivo separado, o código só precisa ser vinculado novamente.
Entenda que o C ++ tem a opção de ter vínculo estático, o que implica que o código do objeto seja corrigido junto com o aplicativo de chamada. Observe que, tanto em C como em C ++, não é inválido ter programação no arquivo de cabeçalho ou até mesmo #include. isso significa apenas que você precisa se preocupar sobre como a vinculação acontece com esses arquivos de objeto.
A situação em Java é muito diferente. Cada arquivo de classe é compilado com o arquivo .class. De fato, a necessidade de compilação de funções de classe de chamador, que é servida como uma seção de cabeçalho no arquivo .class. No entanto, no Java, a vinculação final é feita apenas dentro do Runtime (a máquina virtual) apenas com essa especificação do código de bytes do arquivo de classe.
Veja isso e isso
fonte
Efetivamente, as interfaces e inclusões são os cabeçalhos; as definições são, portanto, idênticas aos binários e não podem estar fora de sincronia. Essa é uma das melhores decisões de design em Java, mas é um incômodo menor que não haja maneira de agrupar essas declarações para compacidade e consistência.
fonte
Um bom motivo para incluir é separar o código que você deseja reutilizar (como definições comuns) do código específico para um determinado projeto. Java quer que você especifique apenas uma classe ou interface por arquivo e isso reduz a necessidade de cabeçalhos incluídos - pois você terá as partes compartilhadas já em seus próprios arquivos.
Além disso, os compiladores e os sistemas de compilação podem querer armazenar em cache os cabeçalhos pré-compilados para evitar a análise mais de uma vez.
fonte