La visibilité de Java et Kotlin est légèrement différente.
public
package private
Définissons une classe Dog qui hérite de la classe Animal dans Kotlin.
open class Animal { //Ajouter open pour en faire une classe héritable
open fun greet() { //Ajouter open pour en faire une fonction remplaçable
}
}
class Dog: Animal() { //Deux points suivi du nom de la classe parente
override fun greet() { //Ajouter un modificateur de remplacement
println("Bow wow")
}
}
Lors de l'héritage d'une classe
class nom de sous-classe
: Ecrire en tant que constructeur de superclasse
.
Regardons le cas où le constructeur a besoin d'arguments.
open class Animal(val name: String) {
open fun greet() {
}
}
//Argument de constructeur de chien`name`Au constructeur de la classe Animal
class Dog(name: String): Animal(name) {
override fun greet() {
println("Bow wow")
}
}
Kotlin n'a pas de modificateur statique.
Si vous souhaitez gérer les membres statiques et les fonctions statiques dans les classes Kotlin, Utilisez un objet compagnon.
Qu'est-ce qu'un objet compagnon? Une instance singleton spéciale.
class Dog {
companion object {
val ancestorName: String = "wolf"
}
fun greet() {
println("Bow wow")
}
}
val ancestor = Dog.ancestorName
J'ai défini une propriété appelée ʻancestorNamedans
l'objet compagnon. Pour accéder à cette propriété, accédez à
Dog.ancestorName` comme s'il s'agissait d'un membre statique.
Kotlin dispose d'un mécanisme pour implémenter facilement un singleton.
object ResourceManager {
fun clean() {
// ...
}
}
ResourceManager.clean()
Vous pouvez définir une classe singleton en suivant le mot-clé ʻobject`. Vous pouvez définir des propriétés et des fonctions comme une classe régulière, Seul le constructeur ne peut pas être défini dans la déclaration d'objet. Utilisez le nom de la classe pour accéder à une instance de singleton. Similaire à l'accès aux membres statiques en Java.
Vous implémentez souvent des classes simples pour stocker des données, non?
data class Point(val x : Int,
val y: Int) {
}
Définissez la classe après le mot-clé data
.
La classe de données considère toutes les propriétés déclarées dans le constructeur principal avec les fonctions suivantes.
De plus, la fonction de copie est automatiquement générée. Il peut être copié tout en modifiant n'importe quelle propriété.
fun moveTo(point: Point, newX: Int): Point {
return point.copy(x = newX)
}
Toutes les propriétés sont déclarées avec val et la classe est Immuable, Vous pouvez facilement générer une copie avec des valeurs réécrites.
La classe scellée est une classe qui ne peut être héritée que dans le même fichier.
sealed class Animal {
}
class Dog: Animal() {
}
class Cat: Animal() {
}
fun greet(animal: Animal) = when(animal) {
is Dog -> "bow wow"
is Cat -> "meow meow"
// else ->Pas besoin d'autre cas!
}
Remarquez lorsque vous êtes dans la fonction d'accueil ci-dessus. Il n'y a pas d'autre cas. C'est l'effet de la classe scellée.
En Java, lors de la définition d'une classe à l'intérieur d'une classe, la signification change selon que le modificateur statique est ajouté ou non. Comparons-le avec la méthode de description de Kotlin.
Java | Kotlin |
---|---|
static class A | class A |
class A | inner class A |
Valeurs par défaut de Kotlin Synonyme de la classe imbriquée de Java avec «static».
Les propriétés Kotlin peuvent être déclarées sur une seule ligne, Il est possible de personnaliser respectivement le getter et le setter.
class Dog(name: String) {
var name: String = name
get() { //Getter personnalisé
//Les variables de champ sont disponibles dans les getters
//Ce getter est dans le nom"Chan"Retour avec
return field + "Chan"
}
set(value) { //Sertisseur personnalisé
//Setter spécifie le nom de l'argument
//Ce setter supprime l'espace blanc à l'avant du nom et le définit dans le champ
field = value.trimMargin()
}
}
Les classes Kotlin ne peuvent pas être héritées par défaut. Il existe un mécanisme pour étendre la fonction sans héritage.
Avec une interface appelée Movable J'ai défini une classe MovableImpl qui implémente Movable.
interface Movable {
fun walk()
fun run()
fun currentCount(): Int
}
class MovableImpl: Movable {
private var count: Int = 0
override fun walk() {
this.count += 1
}
override fun run() {
this.count += 3
}
override fun currentCount(): Int = this.count
}
Définissez une classe Dog qui étend les fonctionnalités de ce Movable.
class Dog(movable: MovableImpl): Movable by movable {
}
À la suite du mot-clé by
, spécifiez l'instance à laquelle la fonctionnalité Movable est déléguée.
Cette classe Dog n'a pas d'implémentation pour l'interface Movable,
Il est automatiquement délégué à MovableImpl.
val dog = Dog(MovableImpl())
dog.walk()
dog.walk()
dog.run()
println(dog.currentCount()) // 5
Vous pouvez déléguer le comportement des getters et des setters de propriété. Définissez une classe comme celle-ci.
class Dog {
var name: String by NameFormatter()
}
class Cat {
var name: String by NameFormatter()
}
Les classes Dog et Cat ont toutes deux une propriété appelée name.
Les deux spécifient by
suivi de NameFormatter.
Essayez d'exécuter le code ci-dessous.
val dog = Dog()
dog.name = "Pochi"
println(dog.name) //Pochi-chan
val cat = Cat()
cat.name = "Marbre"
println(cat.name) //Tama-chan
Dans les deux cas, les espaces sont supprimés de la chaîne de caractères affectée au nom. Dans le getter, "chan" est ajouté comme suffixe.
Jetons maintenant un œil à l'implémentation de NameFormatter.
class NameFormatter {
private var name: String = ""
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return this.name + "Chan"
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
this.name = value.trimStart()
}
}
Implémentez les méthodes getValue
et setValue
en suivant le mot-clé ʻoperator`.
De cette manière, le comportement de la propriété peut être délégué à l'extérieur.
Recommended Posts