This article is only for recording learning, so if there are some mistakes or wrong understanding, please correct.

Kotlin’s Study Notes (3)

Description:

  1. Simple use of interfaces in Kotlin
  2. Inheritance of classes and properties in Kotlin
  3. Overloaded functions of classes in Kotlin
  4. Introduction to modifiers in Kotlin
  5. Kotlin’s explanation of nested classes inside classes
  6. Kotlin’s primary and secondary constructors

1. The interface

Kotlin is a little different than the Java interface

Kotlin’s interface declarations are final and public by default. Interfaces in Kotlin are similar to Java 1.8 interfaces in that they can contain both abstract method definitions and non-abstract method implementations

/ / interface
interface Clicker{
    fun click(a)
}

/ / implementation class
class MeButton : Clicker{
    override fun click(a) {
        println("not implemented")}}/ / call
fun main(args: Array<String>) {
    var button:MeButton = MeButton()
    button.click()
}
Copy the code

In the above code, we see that Kotlin uses “:” instead of extends and implements in Java. Like Java, Kotlin has a single inheritance, but can implement multiple interfaces. Similar to @override in Java, override is used to annotate methods that inherit from a parent class, or methods or properties of an interface. The difference is that override in Kotlin is mandatory, so you avoid overwriting the implementation method before adding an abstract method. Kotlin interfaces can have methods implemented by default, but Java requires the default keyword in the method. Kotlin does not need to add the keyword.

interface Clicker{
    fun click(a)
    fun staticClick(a){
        println("Default implementation")}}Copy the code

If you implement the interface, you can also inherit the method and modify it, or you can not implement the method.

1. If you inherit two interfaces that have the same default implementation function, if you do not explicitly specify which one to call, the runtime will report an error. 2.1 super< AInterface >.click(); super< BInterface >.click(); In Java, the expression is ainterface.super.click (); It’s presented in a different way

2. The inheritance

2.1 Inheritance Function

In Java, superclasses are inherited by default, so we need to be careful when writing baseActivities or Basefragments, because careless subclasses will implement many classes that do not exist. So all methods in Kotlin are final by default, and if you want to subclass, you have to mark the open modifier specifically.

class MeButton : Clicker{
    override fun click(a) {  // Implement Clicker methods that are open inheritable by default
        println("not implemented")}fun dieable(a){}   // The default is final

    open fun openClass(a){}  // make it clear that open is inheritable
}
Copy the code

For methods that implement base classes or interfaces, the default is open. If you want to change this, you can add the modifier final.

All classes in Kotlin have a common superclass Any, which is the default superclass for classes that do not have a supertype declaration

2.2 Inherited Attributes

Inherited properties are similar to inherited functions. Properties declared in a parent class and then redeclared in a child class must start with Override, and they must have a compatible type. Each declared property can be overridden by a property that has an initializer or a property that has a getter method. Note: the var attribute can inherit from a val attribute, but not vice versa. (Var attribute cannot be inherited by val)

interface Foo {
    val count: Int
}

class Bar1(override val count: Int) : Foo

class Bar2 : Foo {
    override var count: Int = 0
}
Copy the code

In the above code, we can also use Override in the main constructor.

2.3 the abstract

Let’s take a look at abstract with a piece of code

// Abstract class, cannot create instance
abstract class abClas{
	// Abstract methods default to open (omitted) cannot be instantiated, and must inherit implementation
    abstract fun  ab1(a)
	// Methods in an abstract class are not open by default, so they need to be specified
    open fun ab2(a){}
    
    fun ab3(a){}}Copy the code

Other places are similar to Java, so I won’t go into much detail here

2.4 Overloaded Functions

Since there is no concept of default value parameters in Java, when we need to call the default value overload function in Kotlin from Java, we must specify all parameter values in the display. But that’s definitely not what we want, otherwise Kotlin would lose the sense of overloading and not be fully interoperable with Java. So in Kotlin’s case, another option is to use the ** @jvmoverloads ** annotation, which automatically generates multiple overloaded methods for Java to call.

@JvmOverloads
fun <T> joinString(
        collection: Collection<T> = listOf(),
        separator: String = ",",
        prefix: String = "",
        postfix: String = ""
): String {
    return collection.joinToString(separator, prefix, postfix)
}

// Where to call
fun main(args: Array<String>) {
    // Functions use named arguments to improve code readability
    println(joinString(collection = listOf(1.2.3.4), separator = "%", prefix = "<", postfix = ">"))
    println(joinString(collection = listOf(1.2.3.4), separator = "%", prefix = "<", postfix = ">"))
    println(joinString(collection = listOf(1.2.3.4), prefix = "<", postfix = ">"))
    println(joinString(collection = listOf(1.2.3.4), separator = "!", prefix = "<"))
    println(joinString(collection = listOf(1.2.3.4), separator = "!", postfix = ">"))
    println(joinString(collection = listOf(1.2.3.4), separator = "!"))
    println(joinString(collection = listOf(1.2.3.4), prefix = "<"))
    println(joinString(collection = listOf(1.2.3.4), postfix = ">"))
    println(joinString(collection = listOf(1.2.3.4)))}Copy the code

3. The modifier

This is the same as most modifiers in Java, but Java defaults to private, but kotlin defaults to public, and no packages are visible in Kotlin. The newly added modifier is: internal, which means it is only available inside modules.

1. Public is not allowed to access low visibility internal in Kotlin. In Java, it is protected. In Kotlin, it is restricted to classes or subclasses. 3. Class extensions are not private and protected.

4. Nested class inner class

Like Java, Kotlin can package classes within classes, but an inner class cannot access properties of an outer class unless you make special arrangements.

class MeButton : Clicker {
    private var a: Int = 1
    override fun click(a) {
        println("not implemented")}fun dieable(a) {}

    open fun openClass(a) {}
	// The inner keyword is the key
    inner class CButton {
        var b: Int = a
    }
}
Copy the code

As you can see from the code above, I have added a new class, CButton, to the class MeButton. If I do not add inner, I call it a nested class. There is no way to get a reference to the outer class in CButton. If you add inner, it is an inner class and you can get a reference to the outer class.

Class 5.

Classes are an important part of both Java and Kotlin. In the previous pages, we also wrote a lot of class code. Here we will explain in detail.

// Kotlin uses the keyword class to declare classes
class Invoice {... }class Empty
Copy the code

A class declaration consists of a class name, a class header, and a class body surrounded by curly braces. The class head and body are optional; If a class has no body, curly braces can be omitted.

5.1 The main constructor

A class in Kotlin can have a primary constructor and one or more secondary constructors. The primary constructor is part of the class header: it follows the class name.

class Person constructor(firstName: String) {  }

class Person (firstName: String) {  }
Copy the code

This code is a typical constructor. We can use the constructor keyword to describe it, although constructor can be omitted if the class has no other modifiers.

5.2 Initializing init

The initialized code can be placed in an initialization block prefixed with the init keyword.

Initialize the code block

class InitOrderDemo(name: String) {
    
	val secondProperty = "Second property: ${name.length}".also(::println)
	val customerKey = name.toUpperCase()
	val firstProperty = "First property: $name".also(::println)
    init {
        println("First initializer block that prints ${name}")}init {
        println("Second initializer block that prints ${name.length}")}}// Run the code
fun main(args: Array<String>) {
    InitOrderDemo("hello")}Copy the code

The results

Second property: 5
First property: hello
First initializer block that prints hello
Second initializer block that prints 5
Copy the code

The parameters of the main construct can be used either in the initialization block or in the property (val customerKey = name.toupperCase ()). This constructor keyword is required if the constructor has annotations or visibility modifiers, and these modifiers precede it:

public class Customer @Inject constructor(name: String) { }
Copy the code

5.3 constructor

Classes may also declare a subconstructor prefixed with constructor:

class Person {
	// subconstructor
    constructor(parent: Person) {
        parent.children.add(this)}}Copy the code

If a class has a primary constructor, each secondary constructor needs to delegate to the primary constructor, either directly or indirectly through another secondary constructor. Delegate to another constructor of the same class using the this keyword:

The code in the init block actually becomes part of the main constructor. The delegate to the primary constructor is the first statement of the secondary constructor, so all the code in the initializer block is executed before the body of the secondary constructor. Even if the class does not have a primary constructor, this delegate will occur implicitly and the initialization block will still be executed

If a non-abstract class does not declare any constructors, then the program will generate by default a primary constructor with no argument visibility. If you do not want your class to have a public constructor, you need to declare an empty primary constructor with non-default visibility.

Kotlin’s Study Notes (5)