Do you know, do you know? Should be green fat red thin. — Li Qingzhao, “Like a Dream”

Kotlin is known as an object-oriented development language. It also has features of an object-oriented language. The three main features of object – oriented are encapsulation, inheritance and polymorphism. This is a feature of every object-oriented language. Today’s section will focus on the differences between Kotlin inheritance and Java and the unique characteristics of Kotlin.

directory

First, object-oriented characteristics

Object – oriented three characteristics: encapsulation, inheritance, polymorphism

Because the three characteristics of object orientation are too general, and they are not unique to Kotlin. I don’t want to describe it here.

Kotlin inherits classes

In Kotlin, inheriting this feature doesn’t really make much of a difference, except for defining keywords and all the parent classes that are different from the Java language. But since I’ve written this, I’ve written this feature from start to finish, so if you have a Java background, you can go over it.

2.1. Superclass (Any)

In Kotlin, all classes inherit from the Any class, which has no parent type. That is, when we define a class, it inherits from the Any superclass by default

Ex. :

class Demo// There is a definition hereDemoClass, that is, the class inherits from the superclass by default.

Copy the code

The Any class just gives us equals(), hashCode(), and toString(). We can look at the source implementation of the Any class:

package kotlin



/ * *

 * The root of the Kotlin class hierarchy. Every Kotlin class has [Any] as a superclass.

* Look at the source code comment: it means that Any Kotlin class inherits from the [Any] class

* /


public open class Any {



    // Compare equals() to equals()

    public open operator fun equals(other: Any?).Boolean



    // The hashCode() method returns the hash value of the object

    public open fun hashCode(a)Int



    / / the toString () method

    public open fun toString(a): String

}

Copy the code

From the source we can see that it is directly under the kotlin package. And only the three methods shown above are defined. Perhaps you have Java programming experience. In familiar Java, all classes inherit from the Object type by default. The Object class is not much different from Any except that it has a few more methods and attributes. But they are not the same class.

Confusion from the above source code: classes and functions are preceded by the open modifier. So what does this modifier do? Any is the parent of all classes, so we need to define an inherited class. We can define an inherited class by following the syntax and structure of Any. Therefore, the open modifier is the modifier that we define the inherited class

2.2, definitions,

2.2.1 Basic use of inherited classes

  • The key for defining an inherited class is:open. Both classes and members need to use itopenThe keyword.

Definition format:

open classThe name of the class{

.

     open var/valAttribute name = attribute value

.

     open funThe function name(a)

.

}

Copy the code

Example: Here we define an inherited class Demo, and implement two properties and methods, and define a DemoTest to inherit from Demo

open class Demo{



    open var num = 3



    open fun foo(a) = "foo"



    open fun bar(a) = "bar"



}



class DemoTest : Demo() {

    // It's worth noting here that Kotlin uses inheritance using the ':' symbol, whereas Java uses the extends keyword

}



fun main(args: Array<String>) {



    println(DemoTest().num)

    DemoTest().foo()

    DemoTest().bar()



}

Copy the code

The output is:

3

foo

bar

Copy the code

Analysis: As you can see from the above code, DemoTest only inherits the Demo class and does not implement any code structure. You can also use properties and functions in the Demo class. That’s the benefit of inheritance.

2.2.2. Inherit class constructors

This implements a class with no primary constructor and the presence of a primary constructor.

  • No primary constructor

When the implementation class has no primary constructor, each auxiliary constructor must either initialize the base type with the super keyword or delegate to another constructor. Note that in this case, different auxiliary constructors can call different constructors of the base type

Example: Here is an example of a common custom View implementation in Android, which we are familiar with when we specify a component that generally implements the three constructors of an inherited class (base type).

class MyView : View() {



    constructor(context: Context) : super(context)



    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)



    constructor(context: Context, attrs: AttributeSet? , defStyleAttr:Int) : super(context, attrs, defStyleAttr)

}

Copy the code

As you can see, when implementing a class without a primary constructor, super() is used to implement the three constructors of the base class.

  • There are primary constructors

When there is a primary constructor, the primary constructor generally implements the constructor with the most arguments in the base type, and the constructor with the least arguments is simply referenced with this.

Example: Use custom components as an example

class MyView(context: Context? , attrs: AttributeSet? , defStyleAttr:Int)

    : View(context, attrs, defStyleAttr) {



    constructor(context: Context?) : this(context,null.0)



    constructor(context: Context? ,attrs: AttributeSet?) :this(context,attrs,0)



}

Copy the code

2.3 function overloading and rewriting

The overloading and overwriting of functions in Kotlin is pretty much the same as in Java, but here’s an example.

2.3.1. Two special uses of rewrite function

Overriding, or overriding, a method of a base type, whether in Java or Kotlin. But here are two things about Kotlin that are special

  1. When it’s a function in a base class, it doesn’t workopenWhen modifying a function, the name of the function that appears in the implementation class must not be useless as in the base classopenA modifier modifies a function that has the same function name, whether or not the function is in the implementation classoverrideModifier modifier. It’s a little convoluted, but you can see it by looking at the example.

Ex. :

open class Demo{

    fun test(a){}   // Note that this function is not modified with the open modifier

}



class DemoTest : Demo() {



    // Declare a function whose name is the same as that of the base type without the open modifier

    // fun test(){

    // Override fun test(){

}

Copy the code
  1. When a class is not usedopenWhen the modifier is modified, the class defaults tofinal. That is:
class A{}

Copy the code

Is equivalent to

final class A{}   // Note that the 'final' modifier is grayed out in the editor because the default class in Kotlin is final by default

Copy the code

So when a base class inherits from another base class and the second base class does not want to override the method of the first base class, the method of the second base class is modified with the final modifier.

Ex. :

open class A{

    open fun foo(a){}

}



// This class inherits from class A, and class B is also decorated with the open modifier

open class B : A() {



    // The final modifier is used here to disallow overriding foo() of class A

    final override fun foo(a){}

}

Copy the code


Copy the code

2.3.2 method overload

The feature of polymorphism was mentioned at the beginning of this article, and this is where the overloading of methods really comes in. That is, the same function name, function parameters are different. This is the same with Java

This is also true in inherited classes:

Ex. :

open class Demo{

    open fun foo(a) = "foo"

}



class DemoTest : Demo() {



    fun foo(str: String) : String{

        return str

    }



    override fun foo(a): String {

        return super.foo()

    }

}    



fun main(args: Array<String>) {

    println(DemoTest().foo())

    DemoTest().foo("Overloaded function of Foo")

}

Copy the code

The output is:

foo

An overloaded function of foo

Copy the code

2.4. Override attributes

  • Override properties and override methods are essentially the same, but properties cannot be overridden.
  • Overriding a property is a property declared in a base class and then overridden in an implementation class of its base classoverrideKeyword modifier, and its properties have the same type as the properties in the base class. And you can override the value of this property (Getter)

Ex. :

open class Demo{

    open var num = 3

}



class DemoTest : Demo() {

    override var num: Int = 10

}

Copy the code

2.4.1. The difference between val and var in rewriting attributes

Overrides num and overrides it to 10, but it’s worth noting that when a base class’s variable modifier is val, its implementation class can be modified with overrides and var. The reverse is not true.

Ex. :

open class Demo{

    open val valStr = "I'm a property decorated with val."

}



class DemoTest : Demo() {



    / *

* We can rewrite this with val or var.

* But when we use val, we can't have setters (). The editor will return the setters in red

* /




    // override val valStr: String

    // get() = super.valStr



    // override var valStr: String = ""

    // get() = super.valStr



    // override val valStr: String = ""



    override var valStr: String = "abc"

        set(value){field = value}

}



fun main(arge: Array<String> >){

    println(DemoTest().valStr)



    val demo = DemoTest()

    demo.valStr = "1212121212"

    println(demo.valStr)

}

Copy the code

The output is:

abc

1212121212

Copy the code

2.4.2 Use the super keyword with caution in Getter() functions

It’s worth noting here that in real projects you don’t use get() = super.xxx when overriding a property, because that way you call the value of the property in the base class regardless of whether you reassign the property to a new value or support setters ().

Example: Following the example above

class DemoTest : Demo() {



    / *

* Here's how to override the 'super' keyword in the getter() function

* /


    override var valStr: String = "abc",

        get() = super.valStr

        set(value){field = value}

}



fun main(arge: Array<String> >){

    println(DemoTest().valStr)



    val demo = DemoTest()

    demo.valStr = "1212121212"

    println(demo.valStr)

}

Copy the code


Copy the code

The output is:

I am usingvalDecorated attributes

I am usingvalDecorated attributes

Copy the code

PS: Be careful to use the super keyword when rewriting attributes. Otherwise, this is the effect of the example above

2.4.3 override in the main constructor

Example: Base class is the same as above

class DemoTest2(override var num: Int.override val valStr: String) : Demo()



fun main(args: Array<String>){

    val demo2 = DemoTest2(1."Override in constructor")

     println("num = ${demo2.num} \t valStr = ${demo2.valStr}")

}

Copy the code

The output is:

num = 1Overridden in the valStr = constructor

Copy the code

2.5. Coverage rules

The coverage rule here refers to that the implementation class inherits a base class and implements an interface class. When the methods and attributes in my base class and the functions in the interface class have the same name, how to distinguish which attribute or attribute the implementation class implements. This is the same as when a class implements two interface classes that use the same properties or functions

Ex. :

open class A{

    open fun test1(a){ println("Function test1() in base class A")}



    open fun test2(a){println("Function test2() in base class A")}

}



interface B{

    fun test1(a){ println("Function test1() in interface class B")}



    fun test2(a){println("Function test2() in interface class B")}

}



class C : A(),B{

    override fun test1(a) {

        super<A>.test1()

        super<B>.test1()

    }



    override fun test2(a) {

        super<A>.test2()

        super<B>.test2()

    }

}

Copy the code

conclusion

The idea of inheriting classes in Kotlin is a common one to use in projects. I’m sure you can easily use it in your project once you’ve studied it carefully, but inheritance is expensive for a class. When implementing a function that doesn’t need too many integrated properties, object expressions can be used as an advanced function to replace inheritance. If you have experience programming in other object-oriented languages, you only need to know keywords, property/function overrides, and override rules

This article has been collected on GitHub: Jetictors/KotlinLearn, welcome star articles continue to update, can be wechat search “J guy talk” first time read, everyone’s three-in-one is the best power for the old J, you are sure not to wave? If you have any mistakes or suggestions on this blog, please leave comments


Ah hello, five fingers mushroom niang ah, take a phone to scan!