← Kotlin EspañolChapter 08 of 13

Herencia

## Objetivos de Aprendizaje - Comprender la herencia en Kotlin - Trabajar con clases abstractas - Implementar interfaces - Usar delegación de interfaces - Sobrescribir métodos y propiedades ## Herencia de Clases ### Clases Abiertas En Kotlin, las clases son finales por defecto. Usa `open` para permitir herencia: ```kotlin open class Animal(val name: String) { open fun makeSound() { println("Some sound") } } class Dog(name: String) : Animal(name) { override fun makeSound() { println("$name says Woof!") } } fun main() { val dog = Dog("Buddy") dog.makeSound() // Buddy says Woof! } ``` ### Constructor de Superclase ```kotlin open class Person(val name: String, var age: Int) { open fun introduce() { println("I'm $name, $age years old") } } class Student(name: String, age: Int, val grade: String) : Person(name, age) { override fun introduce() { super.introduce() println("I'm in grade $grade") } } fun main() { val student = Student("Alice", 15, "10th") student.introduce() } ``` ## Clases Abstractas ```kotlin abstract class Shape { abstract fun area(): Double fun description() { println("This shape has area: ${area()}") } } class Circle(val radius: Double) : Shape() { override fun area(): Double = Math.PI * radius * radius } class Rectangle(val width: Double, val height: Double) : Shape() { override fun area(): Double = width * height } fun main() { val shapes = listOf(Circle(5.0), Rectangle(4.0, 3.0)) for (shape in shapes) { shape.description() } } ``` ## Interfaces ### Interfaces Básicos ```kotlin interface Drawable { fun draw() } class Circle(val radius: Double) : Drawable { override fun draw() { println("Drawing circle with radius $radius") } } fun main() { val drawable: Drawable = Circle(5.0) drawable.draw() } ``` ### Interface con Implementación por Defecto ```kotlin interface Greeter { fun greet() fun farewell() { println("Goodbye!") } } class Person(val name: String) : Greeter { override fun greet() { println("Hello, I'm $name") } } fun main() { val person = Person("Alice") person.greet() person.farewell() } ``` ### Múltiples Interfaces ```kotlin interface Printable { fun print() } interface Serializable { fun serialize(): String } class Document(val content: String) : Printable, Serializable { override fun print() { println(content) } override fun serialize(): String { return content } } fun main() { val doc = Document("Hello World") doc.print() println(doc.serialize()) } ``` ## Resolución de Conflictos de Interfaces ```kotlin interface A { fun foo() = "A" fun bar() } interface B { fun foo() = "B" fun bar() } class C : A, B { override fun foo() = super.foo() + super.foo() override fun bar() { println("bar() implementation") } } fun main() { val c = C() println(c.foo()) // AB c.bar() } ``` ## Delegación ### Por Interface ```kotlin interface Base { fun print() } class BaseImpl(val x: Int) : Base { override fun print() { println(x) } } class Derived(b: Base) : Base by b fun main() { val b = BaseImpl(10) Derived(b).print() // 10 } ``` ### Ejemplo del Mundo Real ```kotlin interface Coworker { fun work() fun takeBreak() } class Manager(val name: String) : Coworker { override fun work() { println("$name is managing") } override fun takeBreak() { println("$name takes a break") } } class Assistant(manager: Manager) : Coworker by manager { fun scheduleMeeting() { println("Scheduling meeting") } } fun main() { val manager = Manager("Alice") val assistant = Assistant(manager) assistant.work() // Alice is managing assistant.takeBreak() // Alice takes a break assistant.scheduleMeeting() } ``` ## Sobrescribiendo Miembros ### Sobrescribir Métodos ```kotlin open class Base { open fun method() = "Base" } class Derived : Base() { override fun method() = "Derived" } fun main() { val base: Base = Derived() println(base.method()) // Derived } ``` ### Sobrescribir Propiedades ```kotlin open class Person { open val name: String = "Unknown" } class Student : Person() { override val name: String = "Student" } fun main() { println(Student().name) // Student } ``` ### Reglas de Sobrescritura ```kotlin open class A { open fun foo() = "A" open val bar = "A-bar" } interface B { fun foo() = "B" // Default implementation val bar: String // Must be overridden } class C : A(), B { override fun foo() = super.foo() + super.foo() override val bar: String get() = super.bar } fun main() { val c = C() println(c.foo()) // AB println(c.bar) // A-bar } ``` ## Verificación de Tipos y Casting ```kotlin open class Person(val name: String) class Student(name: String, val grade: Int) : Person(name) class Teacher(name: String, val subject: String) : Person(name) fun main() { val people = listOf(Person("John"), Student("Alice", 10), Teacher("Bob", "Math")) for (person in people) { when (person) { is Student -> println("${person.name} is a student in grade ${person.grade}") is Teacher -> println("${person.name} teaches ${person.subject}") is Person -> println("${person.name} is a person") } } } ``` ## Resumen - Las clases son finales por defecto; usa `open` para permitir herencia - Las clases y métodos abstractos usan la palabra clave `abstract` - Las interfaces pueden tener implementaciones por defecto - Una clase puede implementar múltiples interfaces - Usa `super` para llamar a implementaciones padre - La palabra clave `by` delega la implementación de interfaz - Sobrescribe métodos/propiedades con la palabra clave `override` - Los casts inteligentes funcionan después de verificaciones con `is`

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →