Eu presumo que você esteja pensando em linguagens como Java e C #?
Nesses idiomas, os primitivos (como int
) são basicamente um compromisso para o desempenho. Eles não suportam todos os recursos de objetos, mas são mais rápidos e com menos sobrecarga.
Para que os objetos suportem herança, cada instância precisa "saber" em tempo de execução de qual classe é uma instância. Caso contrário, os métodos substituídos não podem ser resolvidos no tempo de execução. Para objetos, isso significa que os dados da instância são armazenados na memória junto com um ponteiro para o objeto de classe. Se essas informações também devem ser armazenadas junto com valores primitivos, os requisitos de memória aumentariam. Um valor inteiro de 16 bits exigiria seus 16 bits para o valor e, adicionalmente, 32 ou 64 bits de memória para um ponteiro para sua classe.
Além da sobrecarga de memória, você também esperaria poder substituir operações comuns em primitivos como operadores aritméticos. Sem a subtipagem, operadores como +
podem ser compilados em uma instrução de código de máquina simples. Se pudesse ser substituído, você precisaria resolver métodos em tempo de execução, uma operação muito mais custosa. (Você deve saber que o C # suporta a sobrecarga do operador - mas isso não é o mesmo. A sobrecarga do operador é resolvida em tempo de compilação, portanto, não há nenhuma penalidade de tempo de execução padrão.)
As cordas não são primitivas, mas ainda são "especiais" na forma como são representadas na memória. Por exemplo, eles são "internados", o que significa que duas cadeias de caracteres literais que são iguais podem ser otimizadas para a mesma referência. Isso não seria possível (ou, pelo menos, muito menos efetivo) se as instâncias de string também mantivessem o controle da classe.
O que você descreve certamente seria útil, mas o suporte exigiria uma sobrecarga de desempenho para cada uso de primitivos e cadeias de caracteres, mesmo quando eles não tirassem proveito da herança.
A linguagem Smalltalk faz (acredito) permitir a subclasse de inteiros. Mas quando o Java foi projetado, o Smalltalk foi considerado muito lento, e a sobrecarga de ter tudo como um objeto foi considerada uma das principais razões. Java sacrificou um pouco de elegância e pureza conceitual para obter melhor desempenho.