interfaz - kotlin data class
Kotlin: ¿por qué usar clases abstractas(vs. interfaces)? (2)
El lado práctico de las clases abstractas es que puede encapsular una parte de la implementación que funciona con el estado, de modo que no se puede anular en las clases derivadas.
En una interfaz, solo puede definir una propiedad sin un campo de respaldo, y una clase de implementación debe anular esa propiedad (ya sea con un campo de respaldo o con accesores personalizados).
Dado esto, no puede definir la lógica que almacena algún estado en una interfaz de una manera confiable: una clase de implementación podría anular las propiedades de una manera inesperada.
Ejemplo:
interface MyContainer {
var size: Int
fun add(item: MyItem) {
// ...
size = size + 1
}
}
Aquí, proporcionamos una implementación predeterminada para add
ese size
incrementos. Pero podría romperse si una clase de implementación se define así:
class MyContainerImpl : MyContainer {
override val size: Int
get() = 0
set(value) { println("Just ignoring the $value") }
}
Por el contrario, las clases abstractas admiten este caso de uso y, por lo tanto, le permiten proporcionar algunas garantías y contratos para todas sus implementaciones: pueden definir algún estado y sus transiciones que se mantendrán igual en una clase derivada.
Aparte de eso, las clases abstractas pueden tener miembros no públicos (internos, protegidos) y miembros finales, mientras que las interfaces no pueden (solo pueden tener miembros privados, que pueden usarse en las implementaciones predeterminadas), y todas sus implementaciones predeterminadas pueden ser anuladas en las clases.
Soy consciente de dos diferencias entre las clases abstractas y las interfaces en Kotlin:
- Una clase abstracta puede tener estado (por ejemplo,
var
...) - Una clase puede implementar múltiples interfaces, pero no múltiples clases abstractas.
Dado que Kotlin es un lenguaje bastante nuevo, me pregunto por qué las clases abstractas no fueron abandonadas. Las interfaces parecen una herramienta superior, con muy poca necesidad de clases abstractas.
Para elaborar: Kotlin admite la implementación de funciones concretas en interfaces, por ejemplo:
interface Shiny {
fun shine(amount : Int) // abstract function
fun reflect(s : String) { print ("**$s**") } // concrete function
}
¿Puede alguien proporcionar un buen ejemplo práctico de la necesidad de clases abstractas?
Las clases abstractas existen esencialmente para una jerarquía de clases. Por ejemplo, si la clase principal abstracta tenía una función concreta que también se definió en la clase secundaria que amplía la clase principal, en ciertos casos sería necesario llamar a la función principal. Cuando se usa una interfaz, es imposible hacerlo debido a la naturaleza completamente abstracta de la clase.