Estoy estudiando clases extendidas en kotlin y encontré este error. Me pueden explicar porque es asi:
open class Animal class Zebra: Animal() fun main() { var animal = Zebra() animal = Animal() // Error: Type mismatch }La inferencia de tipos de Kotlin es una de las funciones de Kotlin más populares en el mundo de JVM. Tan popular que Java 10 también introdujo la inferencia de tipos (limitada en comparación con Kotlin). Sin embargo, existen algunos peligros al usar esta función. Sobre todo, debemos recordar que el tipo inferido de una asignación es el tipo exacto del lado derecho, y no una superclase o interfaz:
En la mayoría de los casos, esto no es un problema. Cuando tenemos un tipo demasiado restrictivo inferido, solo necesitamos especificarlo y nuestro problema está resuelto:
open class Animal class Zebra: Animal() fun main() { var animal: Animal = Zebra() animal = Animal() }Sin embargo, no existe tal comodidad cuando no controlamos una biblioteca u otro módulo. En tales casos, la exposición del tipo inferido puede ser realmente peligrosa. Veamos un ejemplo. Supongamos que tiene la siguiente interfaz utilizada para representar fábricas de automóviles
interface CarFactory { fun produce(): Car }También se usa un automóvil predeterminado si no se especificó nada más:
val DEFAULT_CAR: Car = Fiat126P()Ahora, todas sus fábricas solo pueden producir Fiat126P. No es bueno. Si definió esta interfaz usted mismo, este problema probablemente se detectará pronto y se solucionará fácilmente. Sin embargo, si es parte de la API externa (Elementos (clases, funciones, objetos) que podrían usarse desde algún módulo externo o alguna parte de nuestro código mantenido por diferentes desarrolladores. Por ejemplo, en las bibliotecas, todos son públicos y clases protegidas, funciones y declaraciones de objetos), es posible que los usuarios enojados le informen primero. Excepto que, el tipo de devolución es información importante cuando alguien no conoce bien la API, por lo que, en aras de la legibilidad, debemos hacerlo explícito, especialmente en partes de nuestra API visibles desde el exterior (API tan expuesta).
La var animal = Zebra() es solo un azúcar sintáctico para
var animal:Zebra = Zebra()esto debe quedar claro.
Entonces la pregunta ¿por qué no podemos asignar superclase? Porque los métodos están siendo llamados a objetos, no a referencias . Si en el futuro la clase Zebra tuviera el método fun roar() el compilador no podría garantizar que la variable animal pueda ejecutar tal si permitiera asignar allí algo más que declarara el tipo o subclase de este tipo
Lee mas:
Kotlin (en realidad el IDE) infiere el tipo de animal a Zebra:
var animal = Zebra() // animal is of type Zebra animal = Animal() // type mismatch since Animal is not a ZebraSi especifica explícitamente que el tipo sea Animal, puede asignar un Animal en la siguiente línea:
var animal: Animal = Zebra() // animal is of type Animal animal = Animal() // this works