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核心编程