// Kotlin
data class Person(
val name: String,
val age: Int
)
// Usage
val person = Person("John", 30)
println(person.name)John
2025-03-12
val name: String (Kotlin) vs String name (Java)val (final) vs mutables : varval et varclass 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éfautinitopenbypublicopen 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()}")
}initfinal 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
fieldlateinitInteropérabilité Bidirectionnelle
Utilisation de Java en Kotlin
📤 Utilisation de Kotlin en Java
@JvmStatic pour méthodes statiques@JvmField pour champs publics@JvmOverloads pour paramètres optionnels@JvmName pour noms personnalisés⚠️ Points d’Attention
sdk install kotlinE. Bruno - Introduction à Kotlin