继承是面向对象编程语言的重要函数。继承允许将现有类(或基类或父类)的函数继承到新类(或派生类或子类)。
主类称为超类(或父类),而继承超类的类称为子类。子类包含超类及其自身的函数。
当两个或多个类具有相同的属性时,就可以使用继承的概念。它允许代码可重用。派生类仅具有一个基类,但可以具有多个接口,而基类可以具有一个或多个派生类。
在Kotlin中,派生类使用类标题中的:运算符继承基类。
open class Base(p: Int){ } class Derived(p: Int) : Base(p){ }
假设无涯教程有两个不同的类“ Programmer”和“ Salesman”,它们具有共同的属性“ name”,“ age”和“ salary”,以及它们各自独立的函数doProgram()和fieldWork()。继承函数使无涯教程可以继承(Employee)包含通用函数。
open class Employee(name: String, age: Int, salary: Float) { //code of employee } class Programmer(name: String, age: Int, salary: Float): Employee(name,age,salary) { //code of programmer } class Salesman(name: String, age: Int, salary: Float): Employee(name,age,salary) { //code of salesman }
所有Kotlin类都有一个公共的超类“ Any”。它是没有明确指定超类的类的默认超类。
例如,类Example隐式继承自Any。
class Example
由于Kotlin类默认为final类,因此不能简单地继承它们。无涯教程在类之前使用open关键字来继承一个类并将其设置为非最终形式,
例如:
open class Example{ // 我现在可以扩展了! }
当无涯教程继承一个类以派生类时,所有字段和函数都会被继承。无涯教程可以在派生类中使用这些字段和函数。
例如:
open class Base{ val x = 10 } class Derived: Base() { fun foo() { println("x is equal to " + x) } } fun main(args: Array<String>) { val derived = Derived() derived.foo() }
输出:
x is equal to 10
open class Bird { fun fly() { println("flying...") } } class Duck: Bird() { fun swim() { println("swimming...") } } fun main(args: Array<String>) { val duck = Duck() duck.fly() duck.swim() }
输出:
flying... swimming...
在这里,无涯教程声明一个类Employee为超类,而Programmer和Salesman是其子类。子类继承属性name,age和salary,并且子类包含其自己的函数,例如doProgram()和fieldWork()。
open class Employee(name: String, age: Int, salary: Float) { init { println("Name is $name.") println("Age is $age") println("Salary is $salary") } } class Programmer(name: String, age: Int, salary: Float):Employee(name,age,salary){ fun doProgram() { println("programming is my passion.") } } class Salesman(name: String, age: Int, salary: Float):Employee(name,age,salary){ fun fieldWork() { println("travelling is my Learnfk.") } } fun main(args: Array<String>){ val obj1 = Programmer("Ashu", 25, 40000f) obj1.doProgram() val obj2 = Salesman("Ajay", 24, 30000f) obj2.fieldWork() }
输出:
Name is Ashu. Age is 25 Salary is 40000.0 programming is my passion. Name is Ajay. Age is 24 Salary is 30000.0 travelling is my Learnfk.
如果在这种情况下,基类和派生类都具有主构造函数,则在基类的主构造函数中初始化参数。在上面的继承示例中,所有类都包含三个参数“ name”,“ age”和“ salary”,并且所有这些参数都在基类的主构造函数中初始化。
当基类和派生类在其主构造函数中都包含不同数量的参数时,则从派生类对象初始化基类参数。
例如:
open class Employee(name: String,salary: Float) { init { println("Name is $name.") println("Salary is $salary") } } class Programmer(name: String, dept: String, salary: Float):Employee(name,salary){ init { println("Name $name of department $dept with salary $salary.") } fun doProgram() { println("Programming is my passion.") } } class Salesman(name: String, dept: String, salary: Float):Employee(name,salary){ init { println("Name $name of department $dept with salary $salary.") } fun fieldWork() { println("Travelling is my Learnfk.") } } fun main(args: Array<String>){ val obj1 = Programmer("Ashu", "Development", 40000f) obj1.doProgram() println() val obj2 = Salesman("Ajay", "Marketing", 30000f) obj2.fieldWork() }
输出:
Name is Ashu. Salary is 40000.0 Name Ashu of department Development with salary 40000.0. Programming is my passion. Name is Ajay. Salary is 30000.0 Name Ajay of department Marketing with salary 30000.0. Travelling is my Learnfk.
创建派生类的对象时,它将首先调用其超类,并执行基类的init块,然后执行其自身的块。
如果派生类不包含任何主构造函数,则需要使用super关键字从派生类调用基类的辅助构造函数。
例如
open class Patent { constructor(name: String, id: Int) { println("execute super constructor $name: $id") } } class Child: Patent { constructor(name: String, id: Int, dept: String): super(name, id) { print("execute child class constructor with property $name, $id, $dept") } } fun main(args: Array<String>) { val child = Child("Ashu",101, "Developer") }
输出:
execute super constructor Ashu: 101 execute child class constructor with property Ashu, 101, Developer
在上面的示例中,创建Child类的对象时,它将调用其构造函数并使用值“ Ashu”,“ 101”和“ Developer”初始化其参数。同时,Child类构造函数使用具有name和id值的super关键字调用其超级类构造函数。由于存在super关键字,因此超类构造函数的主体首先执行,然后返回Child类构造函数。
方法覆盖是指将父类(父类)的方法具体实现到其子类(子类)。
换句话说,当子类将其超类的方法重新定义或修改为子类时,称为方法重写。方法重写只能在继承中进行。
open class Bird { open fun fly() { println("Bird is flying...") } } class Parrot: Bird() { } class Duck: Bird() { } fun main(args: Array<String>) { val p = Parrot() p.fly() val d = Duck() d.fly() }
输出:
Bird is flying... Bird is flying...
在上面的示例中,没有覆盖基类方法的程序,无涯教程发现派生类Parrot和Duck都执行相同的通用操作。为了克服这个问题,无涯教程使用方法覆盖的概念。
链接:https://www.learnfk.comhttps://www.learnfk.com/kotlin/kotlin-inheritance.html
来源:LearnFk无涯教程网
在此示例中,父类Bird的fly()方法在其子类Parrot和Duck中被覆盖。要覆盖父类的方法,必须将要覆盖的父类及其方法声明为open。同时,在子类中被覆盖的方法必须以关键字override作为开头。
open class Bird { open fun fly() { println("Bird is flying...") } } class Parrot: Bird() { override fun fly() { println("Parrot is flying...") } } class Duck: Bird() { override fun fly() { println("Duck is flying...") } } fun main(args: Array<String>) { val p = Parrot() p.fly() val d = Duck() d.fly() }
输出:
Parrot is flying... Duck is flying...
与方法类似,超类的属性也可以在其子类中被覆盖。 Bird类的color属性在其子类Parrot和Duck中被覆盖并进行了修改。
open class Bird { open var color = "Black" open fun fly() { println("Bird is flying...") } } class Parrot: Bird() { override var color = "Green" override fun fly() { println("Parrot is flying...") } } class Duck: Bird() { override var color = "White" override fun fly() { println("Duck is flying...") } } fun main(args: Array<String>) { val p = Parrot() p.fly() println(p.color) val d = Duck() d.fly() println(d.color) }
输出:
Parrot is flying... Green Duck is flying... White
无涯教程可以在继承中使用var属性覆盖val属性,但反之亦然。
派生类也可以使用 super 关键字调用其超类方法和属性。
例如:
open class Bird { open var color = "Black" open fun fly() { println("Bird is flying...") } } class Parrot: Bird() { override var color = "Green" override fun fly() { super.fly() println("Parrot is flying...") } } fun main(args: Array<String>) { val p = Parrot() p.fly() println(p.color) }
输出:
Bird is flying... Parrot is flying... Green
在Kotlin中,派生类在实现多个类中提供的相同函数名称时,在尖括号中使用超类名称,例如gsuper <Base>。
例如,派生类Parrotextends继承其超类Bird,并实现包含相同函数fly()的Duck接口。要调用每个类和接口的特定方法,无涯教程必须在尖括号中提及每个类型的超类型名称,分别为super <Bird> .fly()和super <Duck> .fly()。
open class Bird { open var color = "Black" open fun fly() { println("Bird is flying...") } } interface Duck { fun fly() { println("Duck is flying...") } } class Parrot: Bird(),Duck { override var color = "Green" override fun fly() { super<Bird>.fly() super<Duck>.fly() println("Parrot is flying...") } } fun main(args: Array<String>) { val p = Parrot() p.fly() println(p.color) }
输出:
Bird is flying... Duck is flying... Parrot is flying...
祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)