Estou fazendo o curso coursera de Martin Odersky sobre programação funcional com scala e, por enquanto, aprendi duas coisas que juntas não fazem sentido:
- Scala não suporta herança múltipla
Nothing
é um subtipo de qualquer outro tipo
Essas duas declarações não podem viver juntas, então como exatamente isso é feito? e qual é exatamente o significado de "subtipo de qualquer outro tipo"
Editar 1
Na API Scala , Nothing
é definido como abstract final class Nothing extends Any
... então, como ele pode estender outras classes?
programming-languages
scala
vainolo
fonte
fonte
Nothing
é uma subclasse de todas as outras classes. Diz que é um subtipo de qualquer outro tipo .Respostas:
Subtipagem e herança são duas coisas diferentes!
Nothing
não estende tudo, é um subtipo , apenas se estendeAny
.A especificação [§3.5.2] possui um caso especial que rege a relação de subtipagem de
Nothing
:Onde
<:
basicamente significa "é um subtipo de".Quanto a como isso é feito: não sabemos, é mágica do compilador e um detalhe de implementação.
Muitas vezes, uma linguagem faz coisas que você, como programador, não pode. Como contrapartida de
Nothing
: tudo em Scala herdaAny
, tudo excetoAny
. Por que nãoAny
herda de algo? Você não pode fazer isso. Por que Scala pode fazer isso? Bem, porque Scala estabeleceu as regras, não você.Nothing
ser um subtipo de tudo é apenas outra instância disso.fonte
null
ser atribuível a um campo de todo tipo em Java. Por que isso é possível? Énull
uma instância de toda classe? Não, é possível porque o compilador diz isso. Período.extends
em Java, e não como compor ) você faz isso para subtipagem, afinal.Quando ele diz que Scala não suporta herança múltipla, ele se refere à herança de uma implementação de método várias vezes. Obviamente, você pode implementar várias interfaces / características em uma classe e elas podem até definir o mesmo método, mas não há conflito entre as diferentes implementações devido à linearização de características.
Em geral, se você tem uma classe
C1
com um métodof()
e uma classeC2
também com um métodof()
, a herança múltipla significa que você pode, de alguma forma, herdar as duas implementações def()
. Isso pode levar a vários problemas, que o Scala resolve ao permitir que você herde apenas de uma única classe e, no caso de várias características, selecionando uma implementação com base na ordem das características.Quanto às
Nothing
coisas, são realmente simples, porque nada não possui atributos ou métodos definidos. Portanto, você não pode ter nenhum conflito de herança. Mas suponho que a maior parte da sua surpresa venha de um entendimento diferente da herança múltipla.Depois de entender que a linearização de características elimina efetivamente qualquer ambiguidade da herança, e que não nos referimos à herança de múltiplas características como herança múltipla devido a isso, você deve ficar bem.
Quanto à forma como isso é realizado: o compilador é eventualmente responsável por isso. Consulte a seção 3.5.2 da especificação de idioma Scala , que entre outras propriedades inclui:
Ou, em outras palavras, se você deseja implementar um compilador corretamente, ele deve ser manipulado
Nothing
como um subtipo de tudo por especificação. Por razões óbvias,Nothing
não está definido para estender-se a todas as classes carregadas no sistema, mas a relevância de definirNothing
como subtipo é limitada a todos os locais onde a subtipagem é relevante.Um ponto importante aqui é que não existe instância de tipo
Nothing
, portanto, seu tratamento é estritamente limitado à verificação de tipo, que é tudo no domínio do compilador.fonte