Fonctions d’extension
Fait partie de la section Programmation orientée objet du Journey Kotlin de Coddy. Leçon 30 sur 57.
Une fonction d’extension ajoute une fonction à un type existant sans modifier le code source du type. Son nom s’écrit après le type récepteur et, à l’intérieur, this fait référence au récepteur, ce qui peut également être omis :
fun String.shout() = uppercase() + "!"
fun Int.isEven() = this % 2 == 0À l’intérieur de main :
println("hello".shout())
println(7.isEven())
println(listOf(1, 2, 3, 4).count { it.isEven() })Résultat :
HELLO!
false
2Les extensions fonctionnent également sur vos propres classes, et les propriétés d’extension ajoutent des propriétés calculées. Une extension ne peut pas ajouter d’état stocké et n’accède qu’aux membres publics de son récepteur :
class Temperature(val celsius: Double)
val Temperature.fahrenheit: Double
get() = celsius * 9 / 5 + 32
fun Temperature.describe() = "$celsius C is $fahrenheit F"À l’intérieur de main :
println(Temperature(100.0).describe())Sortie :
100.0 C is 212.0 FLes extensions sont résolues statiquement : le type déclaré de l’expression détermine l’extension lors de la compilation du programme, et non la classe de l’objet. C’est la principale différence avec un membre redéfini :
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"À l’intérieur de main :
val s: Shape = Circle()
println(s.member())
println(s.ext())Sortie :
circle member
shape extensionLorsque la classe possède déjà un membre avec la même signature, le membre l’emporte toujours. Utilisez les membres pour les comportements qui appartiennent au type et peuvent être redéfinis ; utilisez les extensions pour les assistants ajoutés de l’extérieur, comme le formatage d’une classe dont vous n’êtes pas propriétaire :
class Robot {
fun greet() = "member greet"
}
fun Robot.greet() = "extension greet"
fun Robot.wave() = "extension wave"Dans main :
val r = Robot()
println(r.greet())
println(r.wave())Sortie :
member greet
extension waveDéfi
FacileMoney(cents) est fourni dans Money.kt. Écrivez des extensions pour celui-ci dans MoneyExtensions.kt : les propriétés d’extension Int.dollars et Int.cents, qui transforment un nombre en Money (12.dollars correspond à 1200 cents), Money.format(), qui renvoie $12.50 (ou -$3.05 pour les montants négatifs), List<Money>.total(), qui renvoie la somme sous forme de Money, et Money.split(parts), qui répartit le montant en parts montants différant d’au plus un centime, les plus grands en premier.
Le code fourni lit des lignes 12 dollars ou 50 cents, ainsi qu’une dernière ligne contenant le nombre de parts. Il affiche chaque montant, total: $12.50 et split 3: $4.17 $4.17 $4.16.
Votre code doit être placé dans MoneyExtensions.kt et Money.kt. Main.kt contient le code fourni d’entrée/sortie et ne peut pas être modifié.
Essayez vous-même
fun main() {
// Code d'entrée/sortie fourni : le garder tel quel
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() })
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation orientée objet
1Classes et objets
Travailler avec des fichiersDéfinir des classesConstructeurs primairesBlocs init et validationConstructeurs secondairesRécapitulatif - Carte de bibliothèque4Héritage
Classes ouvertes et sous-classesRedéfinition des membressuper et constructeursClasses abstraitesRécapitulatif – Annuaire du personnel2Propriétés et encapsulation
Accesseurs personnalisésModificateurs de visibilitéSetters privéslazy et lateinitRécapitulatif - Compte bancaire5Interfaces
Déclarer des interfacesMéthodes par défautInterfaces multiplesInterfaces en tant que typesRécapitulatif - Méthodes de paiement8Génériques
Fonctions génériquesClasses génériquesContraintes de typeVariance avec in et outRécapitulatif - File de priorité11Projet : Gestion de bibliothèque
Livres et membresEmprunter des livres3Objets et compagnons
Déclarations d’objetsObjets compagnonsConstantes avec constExpressions d’objetsRécapitulatif – Billetterie6Polymorphisme
Dispatch dynamiqueVérifications de types et smart castswhen avec des typesFonctions d’extensionRécapitulatif - Gardien de zooEntraînez-vous par vous-même : Playground Kotlin