Clases abiertas y subclases
Parte de la sección Programación orientada a objetos del Journey de Kotlin de Coddy. Lección 17 de 57.
La herencia permite que una clase se base en otra. La subclase obtiene todas las propiedades y métodos de su superclase y puede añadir los suyos propios. Las clases de Kotlin están cerradas de forma predeterminada, por lo que una clase debe marcarse como open antes de que otra clase pueda extenderla:
open class Animal(val name: String) {
fun describe() = "$name is an animal"
}
class Dog(name: String) : Animal(name) {
fun fetch() = "$name fetches the ball"
}Dentro de main:
val rex = Dog("Rex")
println(rex.describe())
println(rex.fetch())Salida:
Rex is an animal
Rex fetches the ballclass Dog(name: String) : Animal(name) indica que Dog extiende Animal y pasa name al constructor de la superclase. El parámetro no tiene val, porque la propiedad ya existe en Animal. Una clase que no es open no puede extenderse:
class Plant(val name: String)
// class Tree(name: String) : Plant(name) // error: este tipo es final, por lo que no se puede extender
open class Vehicle(val wheels: Int)
class Bike : Vehicle(2) // pasa un valor fijo
class Truck(val load: Int) : Vehicle(6) // añade su propia propiedadUn Dog es un Animal, por lo que una instancia de la subclase puede utilizarse donde se espera el tipo de la superclase. Una List<Animal> puede contener perros, gatos y animales comunes, y cada elemento tiene los miembros de Animal:
open class Animal(val name: String) {
fun describe() = "$name is an animal"
}
class Dog(name: String) : Animal(name)
class Cat(name: String, val indoor: Boolean) : Animal(name)Dentro de main:
val pets: List<Animal> = listOf(Dog("Rex"), Cat("Tom", true), Animal("Generic"))
for (p in pets) println(p.describe())Salida:
Rex is an animal
Tom is an animal
Generic is an animalLa herencia modela una relación es-un: un perro es un animal, una cuenta de ahorros es una cuenta. Cuando una clase solo usa otra (un coche tiene un motor), asígnale en su lugar una propiedad de ese tipo. Las clases cerradas son las predeterminadas de Kotlin, por lo que una clase destinada a la extensión lo indica con open, y todas las demás clases mantienen su comportamiento protegido de las subclases.
open class Account(val owner: String)
class SavingsAccount(owner: String) : Account(owner) // is-a: herencia
class Engine(val horsepower: Int)
class Car(val engine: Engine) // has-a: una propiedadDesafío
FácilManager repite lo que Employee ya tiene. Haz que Employee sea abierta y convierte Manager en su subclase: Manager(name: String, salary: Int) pasa ambos valores a Employee y conserva solo lo nuevo, una lista privada de nombres de subordinados con addReport(name) y teamSize(). En Employee, raise(percent) aumenta el salario en ese porcentaje, redondeando hacia abajo, y describe() devuelve Ada earns 5500.
El código proporcionado crea un gerente a partir de la primera línea (name,salary), añade cada nombre posterior como subordinado, aplica un aumento del 10 % e imprime Ada earns 5500 and leads 2; después comprueba que un gerente es un Employee.
Tu código va en Employee.kt y Manager.kt. Main.kt contiene el código proporcionado de entrada/salida y no se puede editar.
Pruébalo tú mismo
fun main() {
// Código de entrada/salida suministrado: déjalo tal como está
val input = generateSequence(::readLine).toList()
val (name, salary) = input[0].split(",")
val boss = Manager(name, salary.toInt())
for (report in input.drop(1)) boss.addReport(report)
boss.raise(10)
println("${boss.describe()} and leads ${boss.teamSize()}")
println("a manager is an employee: ${(boss as Any) is Employee}")
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación orientada a objetos
1Clases y objetos
Trabajar con archivosDefinir clasesConstructores primariosBloques init y validaciónConstructores secundariosRepaso - Tarjeta de biblioteca4Herencia
Clases abiertas y subclasesSobrescritura de miembrossuper y constructoresClases abstractasRepaso: directorio del personal2Propiedades y encapsulación
Accesores personalizadosModificadores de visibilidadSetters privadoslazy y lateinitRepaso: cuenta bancaria5Interfaces
Declaración de interfacesMétodos predeterminadosInterfaces múltiplesInterfaces como tiposRepaso: métodos de pago8Genéricos
Funciones genéricasClases genéricasRestricciones de tiposVariancia con in y outRepaso - Cola de prioridad11Proyecto: Gestión de biblioteca
Libros y miembrosPréstamo de librosPractica por tu cuenta: Playground de Kotlin