Kotlin Learning (4) - Classes and Objects, Inheritance, Overriding, Abstract Classes, Properties and Fields, Interfaces, Visibility Modifiers, Extensions

1. Classes and Objects

1. Class

The declarations of Kotlin and Java classes are the same, which are represented by class, such as

class TestClass {

}

If it is an empty class, the curly brackets can be omitted

2. Constructor

A primary constructor and multiple secondary functions, the primary function is after the class name, such as

class TestClass {
    //主函数
    class TestClass constructor(firstName: String) {
        init {
            print("这里初始化")
        }
    }
}

The constructor keyword can be omitted if the primary constructor does not have any annotations or visibility modifiers.
and the primary constructor does not allow any code, the initialization code can be placed in the init block

Let's look at the next constructor

Classes can also declare secondary constructors prefixed with constructor:

class Person {
        constructor(parent: Person) {
        parent.children.add(this)
    }
}

3. Instantiate the class object

There is no new in Kotlin, so call it directly

class TestClass {
    //主函数
    class TestClass constructor(firstName: String) {
        init {
            print("这里初始化")
        }
    }
    constructor(firstName: String) {
        print("次构造函数")
    }
}

class Test{

    //实例化类对象
    val test = TestClass("lgl");
}

2. Inheritance

All classes have a superclass Any, which is somewhat similar to Object in JAVA, but they are indeed different, but the concept is similar, because Any has only a few methods

Here we define a base class BaseClass

 open class BaseClass {
     class BaseClass constructor(str:String){

     }
 }

The open here means public, which is the exact opposite of final in JAVA

Then we define another class to inherit the base class

class SonClass : BaseClass(){

}

Of course, the parentheses can be canceled

If the class does not have a primary constructor, then each secondary constructor must use the super keyword to initialize its base type, as we use in Android

class MyView : View {
    constructor(ctx: Context) : super(ctx)
    constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs)
}

3. Coverage

This is easy to understand, it can be overridden with inheritance, let's look at a piece of code

open class Base {
    open fun v() {
        print("Base...")
    }
    fun nv() {}
}

class Son() : Base() {
    override fun v() {
        print("Son...")
    }
}

fun main(args: Array<String>) {
    val son = Son();
    son.v()
}

There is a Base modified by open, there is a Base method in it, and there is printing in it. I now have a Son class, which inherits Base, and overrides the v method with override modification, and then prints it. Then my main method instantiates this object. After the call, the print is Son...

write picture description here

A member marked as override is itself open, that is, it can be overridden in subclasses, and if you don't want to be overridden again, you can modify a final

The above mentioned is the overriding of the method, we can also override the property, but it is the same, need to override the modification, such as


open class Base {

    open var a = 9;

    open fun v() {
        print("Base...")
    }

    fun nv() {}
}

class Son() : Base() {

    override var a = 8;

    override fun v() {
        print("Son...")
    }
}

fun main(args: Array<String>) {
    val son = Son();
    son.v()
    print(son.a)
}

In this code, we can see that an attribute a is defined in the base class, and then an a is overwritten in the subclass, and the output is the a value of the subclass

If we want to use the method of the parent class, we can use super

class Son() : Base() {

    override var a = 8;

    override fun v() {
        super.v()
        print("Son...")
    }
}

If you want to use it in an inner class, you need [email protected]()

In Kotlin, implementation inheritance is governed by the following rules: if a class inherits multiple implementations of the same member from its immediate superclass, it must override the member and provide its own implementation (perhaps with one of the inherited
ones ) a). To indicate which supertype to inherit from, we use super qualified by the supertype name in angle brackets, as in super:

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 {
    // 编译器要求覆盖 f():
    override fun f() {
        super<A>.f() // 调⽤ A.f()
        super<B>.f() // 调⽤ B.f()
    }
}

4. Abstract class

abstract class Impl{
    abstract open fun f()
}

class Impl1():Impl(){

    override fun f() {

    }
}

The open here can not be declared, and we can cover a non-abstract open member with an abstract member, as in the example

    open class Base {
        open fun f() {}
    }
    abstract class Derived : Base() {
        override abstract fun f()
    }

5. Attributes and Fields

I believe that everyone should have a better understanding of attributes, as we have already said in the second article

class H {
    var a: String = "Hello"
    var b: Int = 0
    var c: Boolean = true;
}

if you want to call

fun main(args: Array<String>) {
    val h = H();
    print("a:${h.a}b:${h.b}c:${h.c}")
}

In kt, get and set are more interesting. The correct syntax is:

var <propertyName>[: <PropertyType>] [= <property_initializer>]
    [<getter>]
    [<setter>]

The following code

class H {
    var a: String
        get() = this.toString()
        set(value) {
            a == value
        }
    var b: Int = 0
    val c: Boolean = true
}

I defined the get and set of a

6. Interface

The keyword interface of kt's interface, such as

interface Impl {
    fun A()
    fun B() {
        //可选方法体
    }
}

If you want to implement an interface, you can

class Tests : Impl {

    override fun A() {

    }
    //B方法可以不需要实现
}

You can also define some properties in the interface, but they must be abstract or provide access to the outside world

interface Impl {

    //抽象
    val a: String
    val b: String
        get() = "Hello"

    fun A()
    fun B() {
        //可选方法体
    }
}

class Tests() : Impl {

    override val a: String = "Hello"

    override fun A() {

    }
    //B方法可以不需要实现
}

7. Visibility modifiers

There are four visibility modifiers in kt, private, protected, internal and public, the default is public

  • public everywhere

  • private declaration is visible in his file

  • internal same module is visible

  • protected does not apply to top-level declarations

Another point to note here is that in JAVA, the variables modified in our private can finally be accessed through set/get, but in kt, the outer class cannot access the private members modified by the inner class

8. Expansion

Extensions, extending new functionality of a class or object without subclassing the class or using any kind of design pattern like decorators

To declare an extension function, we need a receiver type, which is the type to be extended, as its prefix. Let's see the code:

fun main(args: Array<String>) {
    val a = listOf<Int>()
    a.open(1, 2)
}

//扩展List一个open方法
fun List<Int>.open(a: Int, b: Int) {
    print(a + b)
}

It is very clear here. A List does not have an open method. I added it by extension, and internally realized the result of the output that I want to add.
Of course , we are not limited to which types, so through generics to decorate

//扩展List一个open方法
fun <T> List<T>.open(a: Int, b: Int) {
    print(a + b)
}

If you are interested, you can come to Github to participate

My public number, looking forward to your attention

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325916762&siteId=291194637