Héritage en Kotlin
En Kotlin, toutes les classes héritent de la classe Any. Elle est la superclasse de toutes les classes, et est la superclasse par défaut des classes sans déclaration explicite de supertype :
class Example // 从 Any 隐式继承
Any fournit trois fonctions par défaut :
equals() hashCode() toString()
Remarque : Any n'est pas java.lang.Object.
Si une classe doit être héritée, elle peut être modifiée avec le mot-clé open.
open class Base(p: Int) // 定义基类 class Derived(p: Int) : Base(p)
Constructeurs
Sous-classe avec un constructeur primaire
Si la sous-classe a un constructeur primaire, la classe de base doit être initialisée immédiatement dans le constructeur primaire.
open class Person(var name : String, var age : Int){// 基类
}
class Student(name : String, age : Int, var no : String, var score : Int) : Person(name, age) {
}
// 测试
fun main(args: Array<String>) {
val s = Student("Example", 18, "S12346", 89)
println("学生名: ${s.name}")
println("年龄: ${s.age}")
println("学生号: ${s.no}")
println("成绩: ${s.score}")
}
Sortie :
学生名: Example 年龄: 18 学生号: S12346 成绩: 89
Sous-classe sans constructeur primaire
Si la sous-classe n'a pas de constructeur primaire, la classe de base doit être initialisée dans chaque constructeur secondaire en utilisant le mot-clé super, ou elle doit déléguer à un autre constructeur. Lors de l'initialisation de la classe de base, différents constructeurs de la classe de base peuvent être appelés.
class Student : Person {
constructor(ctx: Context) : super(ctx) {
}
constructor(ctx: Context, attrs: AttributeSet) : super(ctx,attrs) {
}
}
Exemple
/**用户基类**/
open class Person(name:String){
/**次级构造函数**/
constructor(name:String,age:Int):this(name){
//初始化
println("-------基类次级构造函数---------")
}
}
/**子类继承 Person 类**/
class Student:Person{
/**次级构造函数**/
constructor(name:String,age:Int,no:String,score:Int):super(name,age){
println("-------继承类次级构造函数---------")
println("学生名: ${name}")
println("年龄: ${age}")
println("学生号: ${no}")
println("成绩: ${score}")
}
}
fun main(args: Array<String>) {
var s = Student("Example", 18, "S12345", 89)
}
Sortie :
-------基类次级构造函数--------- -------继承类次级构造函数--------- 学生名: Example 年龄: 18 学生号: S12345 成绩: 89
Redéfinition
Dans une classe de base, lorsqu'une fonction est déclarée avec fun, elle est modifiée en final par défaut et ne peut pas être redéfinie par les sous-classes. Si vous voulez permettre aux sous-classes de redéfinir la fonction, vous devez ajouter manuellement open pour la modifier. Les sous-classes redéfinissent les méthodes en utilisant le mot-clé override :
/**用户基类**/
open class Person{
open fun study(){ // 允许子类重写
println("我毕业了")
}
}
/**子类继承 Person 类**/
class Student : Person() {
override fun study(){ // 重写方法
println("我在读大学")
}
}
fun main(args: Array<String>) {
val s = Student()
s.study();
}
La sortie est :
I am in college.
S'il existe plusieurs méthodes identiques (héritées ou implémentées à partir d'autres classes, telles que les classes A et B), la méthode doit être redéfinie, et le générique super peut être utilisé pour appeler sélectivement l'implémentation de la classe parente.
open class A {
open fun f () { print("A") }
fun a() { print("a") }
}
interface B {
fun f() { print("B") } //接口的成员变量默认是 open 的
fun b() { print("b") }
}
class C() : A() , B{
override fun f() {
super<A>.f()//调用 A.f()
super<B>.f()//调用 B.f()
}
}
fun main(args: Array<String>) {
val c = C()
c.f();
}
C hérite de a() ou b(). C peut non seulement hériter des fonctions de A ou B, mais C peut aussi hériter des fonctions communes à A() et B(). À ce stade, la fonction n'a qu'une seule implémentation dans C. Pour éliminer l'ambiguïté, la fonction doit appeler les implémentations de cette fonction dans A() et B(), et fournir sa propre implémentation.
La sortie est :
AB
Redéfinition de propriété
La redéfinition de propriété utilise le mot-clé override. Les propriétés doivent avoir des types compatibles. Chaque propriété déclarée peut être redéfinie par un initialiseur ou une méthode getter :
open class Foo {
open val x: Int get { …… }
}
class Bar1 : Foo() {
override val x: Int = ……
}
Vous pouvez redéfinir une propriété val par une propriété var, mais pas l'inverse. Parce qu'une propriété val définit elle-même une méthode getter, la redéfinir en tant que propriété var déclare en plus une méthode setter dans la classe dérivée.
Vous pouvez utiliser le mot-clé override dans le constructeur primaire dans le cadre de la déclaration de propriété :
interface Foo {
val count: Int
}
class Bar1(override val count: Int) : Foo
class Bar2 : Foo {
override var count: Int = 0
}
Autres extensions