Kotlin 简明教程
Kotlin - Inheritance
继承可以定义为一个类获取另一个类的成员(方法和属性)的过程。通过使用 inheritance ,信息以分层顺序变得可管理。
Inheritance can be defined as the process where one class acquires the members (methods and properties) of another class. With the use of inheritance the information is made manageable in a hierarchical order.
继承其他类成员的类称为 subclass (派生类或子类),而成员被继承的类称为 superclass (基类或父类)。
A class which inherits the members of other class is known as subclass (derived class or child class) and the class whose members are being inherited is known as superclass (base class or parent class).
继承是面向对象编程的主要特征之一,它允许用户基于现有类创建新类。继承我们可以从基类继承所有特性,并且还可以拥有自己的其他特性。
Inheritance is one of the key features of object-oriented programming which allows user to create a new class from an existing class. Inheritance we can inherit all the features from the base class and can have additional features of its own as well.
Kotlin 中的所有类都有一个名为 Any 的共同超类,这是没有声明父类的类的默认超类:
All classes in Kotlin have a common superclass called Any, which is the default superclass for a class with no supertypes declared:
class Example // Implicitly inherits from Any
Kotlin 超类 Any 有三个方法: equals() 、 hashCode() 和 toString() 。因此,这些方法已为所有 Kotlin 类定义。
Kotlin superclass Any has three methods: equals(), hashCode(), and toString(). Thus, these methods are defined for all Kotlin classes.
在 Kotlin 中,所有内容默认情况下都是 final ,因此,我们需要在类声明前使用关键字 open 使其他类可以继承它。Kotlin 使用运算符 ":" 来继承类。
Everything in Kotlin is by default final, hence, we need to use the keyword open in front of the class declaration to make it inheritable for other classes. Kotlin uses operator ":" to inherit a class.
Example:
看一下下面的继承示例。
Take a look at the following example of inheritance.
open class ABC {
fun think () {
println("Hey!! i am thiking ")
}
}
class BCD: ABC(){ // inheritence happend using default constructor
}
fun main(args: Array<String>) {
var a = BCD()
a.think()
}
当你运行上述 Kotlin 程序时,它将生成以下输出:
When you run the above Kotlin program, it will generate the following output:
Hey!! i am thiking
Overriding Methods
现在,如果我们希望在子类中 override think() 方法。然后,我们需要考虑以下示例,其中我们创建两个类并将其中一个函数覆盖到子类中。
Now, what if we want to override the think() method in the child class. Then, we need to consider the following example where we are creating two classes and override one of its function into the child class.
open class ABC {
open fun think () {
println("Hey!! i am thinking ")
}
}
class BCD: ABC() { // inheritance happens using default constructor
override fun think() {
println("I am from Child")
}
}
fun main(args: Array<String>) {
var a = BCD()
a.think()
}
当你运行上述 Kotlin 程序时,它将生成以下输出:
When you run the above Kotlin program, it will generate the following output:
I am from Child
用关键字 override 标记的成员本身是 open ,因此可以在子类中覆盖它。如果您想禁止重新覆盖它,那么您必须将其 final 如下所示:
A member marked with keyword override is itself open, so it may be overridden in subclasses. If you want to prohibit re-overriding it then you must make it final as follows:
class BCD: ABC() {
final override fun think() {
println("I am from Child")
}
}
Overriding Properties
覆盖机制对属性的工作方式与对方法的工作方式相同。在超类中声明的属性(然后在派生类中重新声明)必须以关键字 override 为前缀,并且它们必须具有兼容的类型。
The overriding mechanism works on properties in the same way that it does on methods. Properties declared on a superclass that are then redeclared on a derived class must be prefaced with the keyword override, and they must have a compatible type.
open class ABC {
open val count: Int = 0
open fun think () {
println("Hey!! i am thinking ")
}
}
class BCD: ABC() {
override val count: Int
init{
count = 100
}
override fun think() {
println("I am from Child")
}
fun displayCount(){
println("Count value is $count")
}
}
fun main(args: Array<String>) {
var a = BCD()
a.displayCount()
}
当你运行上述 Kotlin 程序时,它将生成以下输出:
When you run the above Kotlin program, it will generate the following output:
Count value is 100
我们还可以在主构造函数中将 override 关键字用作属性声明的一部分。以下示例使用主构造函数来覆盖 count 属性,如果没有将任何值传递给构造函数,它将使用 400 作为默认值:
We can also can use the override keyword as part of the property declaration in a primary constructor. Following example makes the use of primary constructor to override count property, which will take default value as 400 in case we do not pass any value to the constructor:
open class ABC {
open val count: Int = 0
open fun think () {
println("Hey!! i am thinking ")
}
}
class BCD(override val count: Int = 400): ABC() {
override fun think() {
println("I am from Child")
}
fun displayCount(){
println("Count value is $count")
}
}
fun main(args: Array<String>) {
var a = BCD(200)
var b = BCD()
a.displayCount()
b.displayCount()
}
当你运行上述 Kotlin 程序时,它将生成以下输出:
When you run the above Kotlin program, it will generate the following output:
Count value is 200
Count value is 400
Derived Class Initialization Order
当我们创建派生类的对象时,构造函数初始化从基类开始。这意味着首先会初始化基类属性,之后将调用任何派生类指令,并且同样适用于任何进一步派生类。
When we create an object of a derived class then constructor initialization starts from the base class. Which means first of all base class properties will be initialized, after that any derived class instructor will be called and same applies to any further derived classes.
这意味着当执行基类构造函数时,在派生类中声明或覆盖的属性尚未初始化。
This means that when the base class constructor is executed, the properties declared or overridden in the derived class have not yet been initialized.
open class Base {
init{
println("I am in Base class")
}
}
open class Child: Base() {
init{
println("I am in Child class")
}
}
class GrandChild: Child() {
init{
println("I am in Grand Child class")
}
}
fun main(args: Array<String>) {
var a = GrandChild()
}
当你运行上述 Kotlin 程序时,它将生成以下输出:
When you run the above Kotlin program, it will generate the following output:
I am in Base class
I am in Child class
I am in Grand Child class
Access Super Class Members
派生类中的代码可以使用 super 关键字直接调用其超类的函数和属性:
Code in a derived class can call its superclass functions and properties directly using the super keyword:
open class Base() {
open val name:String
init{
name = "Base"
}
open fun displayName(){
println("I am in " + this.name)
}
}
class Child(): Base() {
override fun displayName(){
super.displayName()
println("I am in " + super.name)
}
}
fun main(args: Array<String>) {
var a = Child()
a.displayName()
}
当你运行上述 Kotlin 程序时,它将生成以下输出:
When you run the above Kotlin program, it will generate the following output:
I am in Base
I am in Base
Overriding rules
如果子类从其直接超类继承同一成员的多个实现,则它必须覆盖此成员并提供其自己的实现。
If a child class inherits multiple implementations of the same member from its immediate superclasses, then it must override this member and provide its own implementation.
这与从单个父类中继承成员的子类不同,在这种情况下,子类不必提供所有开放成员的实现。
This is different from a child class which inherits members from a single parent, in such case case it is not mandatory for the child class to provide the implementation of all the open members.
open class Rectangle {
open fun draw() { /* ... */ }
}
interface Polygon {
fun draw() { /* ... */ } // interface members are 'open' by default
}
class Square() : Rectangle(), Polygon {
// The compiler requires draw() to be overridden:
override fun draw() {
super<Rectangle>.draw() // call to Rectangle.draw()
super<Polygon>.draw() // call to Polygon.draw()
}
}
从 Rectangle 和 Polygon 中继承是正常的,但它们都有各自的 draw() 方法的实现,因此您需要覆盖 Square 中的 draw() 并提供单独的实现来消除歧义。
It’s fine to inherit from both Rectangle and Polygon, but both of them have their implementations of draw() method, so you need to override *draw()*in Square and provide a separate implementation for it to eliminate the ambiguity.