Menu
Coddy logo textTech

Ridefinizione dei membri

Fa parte della sezione Programmazione orientata agli oggetti del percorso Kotlin di Coddy. Lezione 18 di 57.

Una sottoclasse può sostituire un metodo ereditato con una propria versione. La superclasse contrassegna il metodo come open e la sottoclasse lo dichiara di nuovo con override:

open class Animal(val name: String) {
    open fun sound() = "..."
}
class Dog(name: String) : Animal(name) {
    override fun sound() = "Woof"
}
class Cat(name: String) : Animal(name) {
    override fun sound() = "Meow"
}

All'interno di main:

println(Dog("Rex").sound())
println(Cat("Tom").sound())
println(Animal("Generic").sound())

Output:

Woof
Meow
...

La versione eseguita viene scelta in base alla classe effettiva dell'oggetto, anche quando il tipo della variabile è la superclasse. Anche il codice all'interno della superclasse che chiama un metodo aperto ottiene la versione della sottoclasse:

open class Animal(val name: String) {
    open fun sound() = "..."
    fun speak() = "$name says ${sound()}"
}
class Dog(name: String) : Animal(name) {
    override fun sound() = "Woof"
}

All'interno di main:

val pets: List<Animal> = listOf(Dog("Rex"), Animal("Generic"))
for (p in pets) println(p.speak())

Output:

Rex says Woof
Generic says ...

Anche le proprietà possono essere sottoposte a override allo stesso modo: open val nella superclasse, override val nella sottoclasse, come proprietà normale, proprietà del costruttore o getter calcolato:

open class Shape {
    open val name = "shape"
    open val corners = 0
}
class Triangle : Shape() {
    override val name = "triangle"
    override val corners = 3
}
class Polygon(override val corners: Int) : Shape() {
    override val name: String
        get() = "$corners-gon"
}

All'interno di main:

for (s in listOf(Shape(), Triangle(), Polygon(6))) println("${s.name}: ${s.corners}")

Output:

shape: 0
triangle: 3
6-gon: 6

Un membro contrassegnato con override è di nuovo aperto, quindi una sottoclasse della sottoclasse può sovrascriverlo ancora una volta; final override lo impedisce. Un membro senza open non può essere sovrascritto in alcun modo e una sottoclasse non può dichiarare un membro con la stessa firma:

open class Animal {
    open fun sound() = "..."
    fun sleep() = "zzz"
}
open class Dog : Animal() {
    final override fun sound() = "Woof"
}
class Puppy : Dog() {
    // override fun sound() = "Yip"   // errore: 'sound' in 'Dog' è final
    // fun sleep() = "nap"            // errore: 'sleep' nasconde un membro della superclasse
}
challenge icon

Sfida

Facile

Animal ha legs() (4), sound() (...) e describe(), che restituisce Rex has 4 legs and says Woof, composto da legs() e sound(). Rendi sovrascrivibili legs() e sound() e completa le sottoclassi sovrascrivendo solo questi due metodi: Dog dice Woof, Bird ha 2 zampe e dice Tweet e Snake ha 0 zampe e dice Hiss. describe() resta com'è in Animal.

Il codice fornito legge righe dog,Rex, bird,Pip, snake,Kaa o di qualsiasi altro tipo (un semplice Animal), memorizza gli animali in un'unica List<Animal> e stampa describe() per ciascuno.

Il tuo codice va in Animal.kt, Dog.kt, Bird.kt e Snake.kt. Main.kt contiene il codice fornito per input/output e non può essere modificato.

Provalo tu

fun main() {
    // Codice di input/output fornito: lascialo così com'è
    val input = generateSequence(::readLine).toList()
    val animals = mutableListOf<Animal>()
    for (line in input) {
        val (kind, name) = line.split(",")
        animals.add(when (kind) {
            "dog" -> Dog(name)
            "bird" -> Bird(name)
            "snake" -> Snake(name)
            else -> Animal(name)
        })
    }
    for (a in animals) println(a.describe())
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Playground Kotlin