Java学习中我们知道,继承是面向对象编程语言的一个重要特征。 继承允许将父类的特性继承到子类。子类包含父类的特性以及它自己的特性。
什么是继承
假设我们有两个类Dog,Cat。所有这两个类都有一些属性(数据成员)和一些行为(成员函数)。
Dog跟Cat具有相同的属性 color、size,具有相同的行为eat()、drink()。为什么不创建具有公共属性和行为的泛化类,让这三个类继承该泛化类。此外,除了继承的类之外,这些类可以具有其独特的属性和行为。
Dog类继承了Animal类的所有函数,并添加了一个函数woof(),同样Cat类继承了Animal类的所有函数,并添加了它的独特函数meow()。
继承定义
- 子类在类头中使用冒号
:
操作符来继承基类(在子类名或构造函数之后)。 - 在类之前使用
open
关键字来为其它类继承这个类。 - 当继承一个类来子类时,所有的字段和函数都是继承的。 可以在子类中使用这些字段和函数。
下面我们用kotlin来描述上面的示例:
open class Animal(var color: String, var size: Int) {
init {
println("Animal color is ${this.color} size is ${this.size}")
}
fun eat(){
println("Animal eat")
}
fun drink(){
println("Animal drink")
}
}
class Dog(color: String, size: Int) :Animal(color, size){
fun woof(){
println("${this.javaClass.name} woof")
}
}
class Cat(color: String, size: Int) :Animal(color, size) {
fun meow(){
println("${this.javaClass.name} meow")
}
}
fun main(args: Array<String>) {
val dog = Dog("white",3)
dog.eat()
dog.drink()
dog.woof()
val cat = Cat("black",4)
cat.eat()
cat.drink()
cat.meow()
}
结果:
Animal color is white size is 3
Animal eat
Animal drink
Dog woof
Animal color is black size is 4
Animal eat
Animal drink
Cat meow
覆盖 Kotlin 中的成员函数和属性
如果子类中存在具有相同名称的函数或属性,则我们需要使用override关键字在子类中覆盖它们。
- 要覆盖父类的方法,必须将要覆盖的父类及方法声明为
open
。 - 使用
override
关键字覆盖父类的成员函数。 - 通过重写函数,子类为现有的基类代码提供自己的实现
- 覆盖并不意味着它将更新基类中的代码,该更改仅适用于覆盖函数或其子类的类。
下面我们重写Dog和Cat类的eat、和drink函数:
open class Animal(var color: String, var size: Int) {
init {
println("Animal color is ${this.color} size is ${this.size}")
}
open fun eat(){
println("Animal eat")
}
open fun drink(){
println("Animal drink")
}
}
class Dog(color: String, size: Int) :Animal(color, size){
override fun eat(){
println("${this.javaClass.name} eat")
}
override fun drink(){
println("${this.javaClass.name} drink")
}
fun woof(){
println("${this.javaClass.name} woof")
}
}
fun main(args: Array<String>) {
val dog = Dog("white",3)
dog.eat()
dog.drink()
dog.woof()
}
结果:
Animal color is white size is 3
Dog eat
Dog drink
Dog woof
子类调用父类方法和属性
子类也可以使用super关键字
调用父类方法和属性。
class Dog(color: String, size: Int) :Animal(color, size){
override fun eat(){
super.eat()
println("${this.javaClass.name} eat")
}
override fun drink(){
super.drink()
println("${this.javaClass.name} drink")
}
fun woof(){
println("${this.javaClass.name} woof")
}
}