// Kotlin
data class Person(
val name: String,
val age: Int
)
// Usage
val person = Person("John", 30)
(person.name) println
John
2025-02-28
val name: String
(Kotlin) vs String name
(Java)val
(final) vs mutables : var
val
et var
class Calculator {
// Expression body avec type de retour explicite
fun add(a: Int, b: Int): Int = a + b
// Expression body avec type inféré
fun multiply(a: Int, b: Int) = a * b
// Expression body pour une propriété en lecture seule
val version = "1.0"
// Expression body pour une propriété calculée
val isReady: Boolean
get() = true
// Expression body pour une propriété avec accesseurs personnalisés
var lastOperation: String = ""
private set
get() = "Last: $field"
}
fun main() {
val calc = Calculator()
println("2 + 3 = ${calc.add(2, 3)}")
println("2 * 3 = ${calc.multiply(2, 3)}")
println("Version: ${calc.version}")
println("Ready: ${calc.isReady}")
}
main()
2 + 3 = 5
2 * 3 = 6
Version: 1.0
Ready: true
En Kotlin, la gestion des propriétés de classe est grandement simplifiée par rapport à Java. Par défaut, chaque propriété déclarée génère automatiquement un getter et un setter (pour les propriétés mutables var
). Kotlin permet également de personnaliser ces accesseurs pour ajouter de la logique métier, des validations, ou des calculs. Les propriétés peuvent être en lecture seule (val
), avoir des accesseurs personnalisés, utiliser des backing fields, ou même être calculées à la demande. Cette approche réduit considérablement le code boilerplate tout en maintenant un niveau élevé d’encapsulation.
class Temperature {
// Propriété avec getter/setter par défaut
var celsius: Double = 0.0
// Propriété avec getter/setter personnalisé
var fahrenheit: Double = 32.0
get() = celsius * 9/5 + 32
set(value) {
celsius = (value - 32) * 5/9
}
// Propriété en lecture seule (getter uniquement)
val kelvin: Double
get() = celsius + 273.15
// Backing field protégé avec getter public
private var _data: String = ""
val data: String
get() = _data
}
// Usage
fun main() {
val temp = Temperature()
temp.celsius = 25.0
println("Fahrenheit: ${temp.fahrenheit}") // 77.0
println("Kelvin: ${temp.kelvin}") // 298.15
}
En Kotlin, il n’existe pas de mot-clé static
comme en Java. À la place, Kotlin propose deux mécanismes principaux pour implémenter des fonctionnalités similaires :
Ces deux approches offrent plus de flexibilité que le simple mot-clé static
de Java, tout en permettant une meilleure encapsulation et la possibilité d’implémenter des interfaces. Pour l’interopérabilité avec Java, l’annotation @JvmStatic
permet de générer de véritables membres statiques.
// Companion object - équivalent des membres statiques
class MathUtils {
companion object {
const val PI = 3.14159
fun square(x: Int): Int = x * x
@JvmStatic // Pour utilisation depuis Java
fun cube(x: Int): Int = x * x * x
}
}
// Object declaration - Singleton avec membres statiques
object Configuration {
const val VERSION = "1.0.0"
var apiKey: String = ""
fun initialize() {
println("Configuration initialized")
}
}
// Usage
fun main() {
println(MathUtils.PI)
println(MathUtils.square(4))
Configuration.apiKey = "xyz"
Configuration.initialize()
}
Avantages
Bénéfices
Avantages
// Suspend function
// Fonction asynchrone
suspend fun fetchUser(): User {
delay(1000) // non bloquant
return User("John")
}
// Usage
// Appel asynchrone
GlobalScope.launch {
val user = fetchUser()
println(user)
}
// Flow
// Flux de données asynchrone
flow {
for (i in 1..3) {
delay(100)
emit(i)
}
}.collect { value ->
println(value)
}
Caractéristiques
Types de Classes
// Classe standard
class User(val name: String)
// Data class
data class Person(
val name: String,
val age: Int
)
// Classe abstraite
abstract class Shape {
abstract fun area(): Double
}
// Object (singleton)
object Config {
const val VERSION = "1.0"
}
// Companion object
class Factory {
companion object {
fun create() = Factory()
}
}
Caractéristiques
final
par défautinit
open
by
public
open class Animal(val name: String) {
open fun makeSound() = "..."
}
class Dog(
name: String,
val breed: String
) : Animal(name) {
override fun makeSound() = "Woof!"
init {
println("Dog $name created")
}
}
// Usage
fun main() {
val dog = Dog("Rex", "Labrador")
println("${dog.name} says: ${dog.makeSound()}")
}
init
final
par défautopen
pour permettre l’héritageoverride
explicite obligatoirepublic
par défautprivate
, protected
, internal
// Interface basique
interface Movable {
fun move()
val speed: Int
// Méthode avec implémentation par défaut
fun describe() = "Moving at $speed"
}
// Interface avec propriété par défaut
interface Named {
val name: String
get() = "Unknown"
}
// Implémentation
class Car : Movable, Named {
override val speed = 100
override val name = "Ferrari"
override fun move() = println("Vrooom!")
}
Caractéristiques
by
// Classe générique basique
class Box<T>(var content: T)
// Variance déclarée
interface Source<out T> {
fun next(): T
}
// Contraintes de type
class NumberBox<T : Number>(var value: T)
// Type projection
fun copy(from: Array<out Any>, to: Array<Any>) {
from.forEachIndexed { i, e -> to[i] = e }
}
// Fonctions génériques
fun <T> printBox(box: Box<T>) {
println(box.content)
}
Concepts Clés
in
/out
*
class User {
// Propriété simple
var name: String = ""
// Propriété en lecture seule
val id: Int = 1
// Propriété avec accesseurs
var age: Int = 0
get() = field
set(value) {
if (value >= 0) field = value
}
// Propriété calculée
val isAdult: Boolean
get() = age >= 18
// Propriété avec délégation
val lazy: String by lazy {
println("Computing...")
"Lazy Value"
}
}
Fonctionnalités
field
lateinit
@JvmStatic
pour méthodes statiques@JvmField
pour champs publics@JvmOverloads
pour paramètres optionnels@JvmName
pour noms personnaliséssdk install kotlin