Funzioni di estensione
Fa parte della sezione Programmazione orientata agli oggetti del percorso Kotlin di Coddy. Lezione 30 di 57.
Una funzione di estensione aggiunge una funzione a un tipo esistente senza modificarne il codice sorgente. Il suo nome viene scritto dopo il tipo ricevente e, al suo interno, this fa riferimento al ricevente, che può anche essere omesso:
fun String.shout() = uppercase() + "!"
fun Int.isEven() = this % 2 == 0All'interno di main:
println("hello".shout())
println(7.isEven())
println(listOf(1, 2, 3, 4).count { it.isEven() })Output:
HELLO!
false
2Le estensioni funzionano anche con le tue classi, e le proprietà di estensione aggiungono proprietà calcolate. Un'estensione non può aggiungere uno stato memorizzato e può accedere solo ai membri pubblici del suo ricevente:
class Temperature(val celsius: Double)
val Temperature.fahrenheit: Double
get() = celsius * 9 / 5 + 32
fun Temperature.describe() = "$celsius C is $fahrenheit F"All'interno di main:
println(Temperature(100.0).describe())Output:
100.0 C is 212.0 FLe estensioni vengono risolte staticamente: è il tipo dichiarato dell’espressione a determinare l’estensione in fase di compilazione del programma, non la classe dell’oggetto. Questa è la differenza principale rispetto a un membro sottoposto a override:
open class Shape {
open fun member() = "shape member"
}
class Circle : Shape() {
override fun member() = "circle member"
}
fun Shape.ext() = "shape extension"
fun Circle.ext() = "circle extension"All'interno di main:
val s: Shape = Circle()
println(s.member())
println(s.ext())Output:
circle member
shape extensionQuando la classe ha già un membro con la stessa firma, il membro ha sempre la precedenza. Usa i membri per i comportamenti che appartengono al tipo e che possono essere sovrascritti; usa le estensioni per gli helper aggiunti dall’esterno, ad esempio per formattare una classe che non possiedi:
class Robot {
fun greet() = "member greet"
}
fun Robot.greet() = "extension greet"
fun Robot.wave() = "extension wave"Dentro main:
val r = Robot()
println(r.greet())
println(r.wave())Output:
member greet
extension waveSfida
FacileMoney(cents) è fornito in Money.kt. Scrivi le estensioni in MoneyExtensions.kt: le proprietà di estensione Int.dollars e Int.cents, che trasformano un numero in Money (12.dollars corrisponde a 1200 centesimi), Money.format(), che restituisce $12.50 (o -$3.05 per gli importi negativi), List<Money>.total(), che restituisce la somma come Money, e Money.split(parts), che suddivide l'importo in parts importi che differiscono al massimo di un centesimo, con quelli più grandi per primi.
Il codice fornito legge righe come 12 dollars o 50 cents e un'ultima riga con il numero di parti. Stampa ogni importo, total: $12.50 e split 3: $4.17 $4.17 $4.16.
Il tuo codice va inserito in MoneyExtensions.kt e Money.kt. Main.kt contiene il codice fornito per l'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 amounts = input.dropLast(1).map { line ->
val (n, unit) = line.split(" ")
if (unit == "dollars") n.toInt().dollars else n.toInt().cents
}
for (m in amounts) println(m.format())
val total = amounts.total()
println("total: ${total.format()}")
val parts = input.last().toInt()
println("split $parts: " + total.split(parts).joinToString(" ") { it.format() })
}
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
1Classi e oggetti
Lavorare con i fileDefinire le classiCostruttori primariBlocchi init e convalidaCostruttori secondariRiepilogo - Tessera della biblioteca4Ereditarietà
Classi aperte e sottoclassiRidefinizione dei membrisuper e costruttoriClassi astratteRiepilogo - Elenco del personale2Proprietà e incapsulamento
Accessor personalizzatiModificatori di visibilitàSetter privatilazy e lateinitRipasso - Conto bancario5Interfacce
Dichiarare le interfacceMetodi predefinitiInterfacce multipleLe interfacce come tipiRiepilogo - Metodi di pagamento8Tipi generici
Funzioni genericheClassi genericheVincoli sui tipiVarianza con in e outRiepilogo - Coda con priorità11Progetto: Gestione della biblioteca
Libri e sociPrendere in prestito i libri3Oggetti e companion
Dichiarazioni di oggettiOggetti companionCostanti con constEspressioni oggettoRipasso - Biglietteria6Polimorfismo
Dispatch dinamicoControlli di tipo e smart castwhen con i tipiFunzioni di estensioneRipasso - Custode dello zooEsercitati da solo: Playground Kotlin