Kotlin面向对象总结-构造函数

kotlin中通过class结构体来声明一个类。

//Kotlin中的类
class PayBird {

    val weight: Double = 100.0
    val color: String = "blue"
    val age: Int = 1
    fun fly() {
        
    }
}

一些特点:

1.不可变属性成员。Kotlin用 val在类中声明引用不可变的属性成员,利用Java中的final修饰符来实现,使用var声明的属性则反之引用可变。

2.属性默认值。因为java的属性都有默认值。比如int类型默认值为0,引用类型的默认值为null。但是在Kotlin中,除非显示地声明延迟初始化,否则就必须指定属性的默认值。

3.不同的可访问修饰符。Kotlin类中的成员默认是全局可见(public),而java的默认可见域是包作用域,Java 中需要主动采用 public修饰才能达到相同的效果。

可带有属性和默认方法的接口

Java8 中的接口

//Java 8中的接口
public interface PayFlyer {

    public String kind();

    default public void fly() {
        System.out.println("I can fly");
    }
}

Java 8引入了一个新特性——接口方法支持默认实现。这使得我们在向接口中新增方法的时候,之前继承过该接口的类则可以不需要实现这个新方法。

Kotlin中的接口

Kotlin支持抽象属性。

//Kotlin中的接口
interface KPayFlyer {

    val speed: Int
    fun kind()
    fun fly() {
        println("I can fly")
    }
}

Kotlin是基于Java 6的,下面是Koltin转java代码:

public interface KPayFlyer {
   int getSpeed();

   void kind();

   void fly();
   
   //静态内部类
   public static final class DefaultImpls {
      public static void fly(KPayFlyer $this) {
         String var1 = "I can fly";
         System.out.println(var1);
      }
   }
}

Kotlin编译器是通过定义一个静态内部类DefaultImpls来提供fly方法的默认实现,虽然Kotlin接口支持属性声明,然而它在java源码中是通过一个get方法来实现的。在接口中的属性并不能像Java接口那样,直接赋值一个常量。

Kotlin通过get()方法进行赋值。

//Kotlin中的接口
interface KPayFlyer {

    val speed: Int
        get() = 100

    fun kind()
    fun fly() {
        println("I can fly")
    }
}

Kotlin接口中的属性背后其实是用方法来实现的,所以说如果要给变量赋值常量,那么就需要编译器原生就支持方法默认实现。但Kotlin是基于java6的,java6不支持这种特性,所以在kotlin 中不能像Java那样给一个接口的属性直接赋值一个常量。

在kotlin中定义一个接口,并在接口中定义一个普通属性,如果没有指定默认行为,则在实现该接口的类中必须对该属性进行初始化。

interface KIPerson {

    val height: Int
}

class Person : KIPerson {
    override val height: Int
        get() = 175
}

更简洁地构造类对象

Kotlin中没有new关键字。Kotlin引入新的构造方法。

1.构造方法默认参数。

因为默认值的存在,创建一个类对象时,最好指定参数名称,否则必须按照实际参数的顺序进行赋值。

构造函数参数可以使用val或者var声明。

class PayFlyingAnimal(val weight: Double = 2.00, val age: Int = 0, val color: String = "blue")
//{}可以省略

val a = PayFlyingAnimal()

val b = PayFlyingAnimal(color = "black")

val c = PayFlyingAnimal(weight = 1000.00, color = "green")

实际上,构造方法的参数名前当然可以没有var和val,但是带上var 或者 val后相当于PayFlyingAnimal类内部声明了一个同名属性,可以用this来进行调用。

class PayFlyingAnimal(var weight: Double = 2.00, var age: Int = 0, var color: String = "blue") {

    init {//构造函数的参数可以在init语句块被调用
        this.weight = 3.00
        this.age = 1
        this.color = "green"
    }
}



class PayFlyingAnimal(weight: Double = 2.00, age: Int = 0, color: String = "blue") {

    val weight: Double
    val age: Int
    val color: String

    init {//构造函数的参数可以在init语句块被调用
        this.weight = 3.00
        this.age = 1
        this.color = "green"
    }
}

2.init 语句块

kotlin引入init语句块的语法,它属于构造方法的一部分,但在表现上是分离的。PayFlyingAnimal类的构造方法在类的外部,它只能对参数进行赋值。如果我们需要

在初始化的时候进行其他额外的操作,可以在init语句块中执行。

构造方法的参数在init语句中直接被调用。

class PayFlyingAnimal(weight: Double = 2.00, age: Int = 0, color: String = "blue") {
    init {
        println("do other things")
        println("the weight is ${weight}")
    }
}

fun main() {
    val a = PayFlyingAnimal()
}

//可以直接初始化类内部的成员属性。

class PayFlyingAnimal(weight: Double = 2.00, age: Int = 0, color: String = "blue") {

    val weight: Double = weight
    val age: Int = age
    val color: String = color

    init {
        println("do other things")
        println("the weight is ${this.weight}")
        println("the age is ${this.age}")
        println("the color is ${this.color}")
    }
}

未用val或者var修饰的参数会存在一个使用问题:

//错误
class PayFlyingAnimal(weight: Double = 2.00, age: Int = 0, color: String = "blue") {

   fun printWeight() {
       println(weight)//这里会报错
   }
}

//正确
class PayFlyingAnimal(var weight: Double = 2.00, val age: Int = 0, var color: String = "blue") {

   fun printWeight() {
       println(weight)
   }
}

构造方法可以有多个init,它们会在对象被创建时按照类中从上到下的顺序先后执行。

多个init语句块有利于进一步对初始化到操作进行职能分离。

class PayFlyingAnimal(weight: Double = 2.00, age: Int = 0, color: String = "blue") {

    val weight: Double = weight
    val age: Int = age
    val color: String = color

    init {
        println("do other things")
        println("the weight is ${this.weight}")
        println("the age is ${this.age}")
    }

    init {
        println("the color is ${this.color}")
    }
}

fun main() {
    val a = PayFlyingAnimal()
}

do other things
the weight is 2.0
the age is 0
the color is blue

可以在init 中对属性进行初始化

class PayFlyingAnimal(val weight: Double, val age: Int, val color: String) {
    val sex: String

    init {
        this.sex = if (this.color == "yellow") "male" else "female"
    }

}

正常情况下,Kotlin规定类中的所有非抽象属性成员都必须在对象创建时被初始化值。

 参考kotlin核心编程

发布了166 篇原创文章 · 获赞 162 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/zhangying1994/article/details/104150567