正文:
在KotLin里定义类的形式如下:
class Invoice {
}
类的声明包括类的名称、类的标题(类的参数、主构造参数)和类主体、所包含的花括号,类的标题和类主体是可选择的,如果类的主体不存在则花括号可以省略形如:
class Empty
class Person constructor(firstName: String) {
}
如果类没有注释和是否可见修饰(public private)
class Person(firstName: String) {
}
主构造函数不包括任何的代码,如果想做初始化操作可以在init代码块中进行初始化
class Customer(name: String) {
init {
logger.info("Customer initialized with value ${name}")
}
}
在init初始化代码块中可以访问主构造函数的参数,在类主体也可以访问在初始化代码块操作之后的值,形如:
class Customer(name: String) {
val customerKey = name.toUpperCase()
init{
System.out.println("执行了初始化代码块")
var ini : Int = 10
var str : String = "Andly"
}
constructor(n : Int) : this(""){
//这里不能访问name
System.out.println("执行了辅助代码")
}
}
事实上声明参数和初始化他们可以在主构造函数,在KotLin有这个用法。形如:(var是可变的,val是只读)
class Person(val firstName: String = "a", val lastName: String = "b", var age: Int) {
}
class Person {
constructor(parent: Person) {
parent.children.add(this)
}
}
如果一个类中有了主构造函数,那么在定义辅助构造函数的时候也需要对主构造函数进行初始化(直接或间接).形如:
class Person(val name: String) {
//直接初始化主构造函数
constructor(name: String, parent: Person) : this(name) {
}
//间接初始主构造函数
constructor(a : Int) : this("",Person("")){
}
}
如果你定义类不是一个抽象类并且没有声明构造函数(主构造和辅助构造函数)那么你的主构造函数是public的,如果你不想让你的主构造函数是public的话,你只需要在
constructor前面加上你的修饰符。形如:
class DontCreateMe private constructor () {
}
tip:如果在构造函数声明了参数,那么那参数会根据类型分配默认值
val invoice = Invoice()
val customer = Customer("Joe Smith")
在KotLin没有new关键字
显示声明父类,形如:
open class Base(p: Int)
class Derived(p: Int) : Base(p)
如果这个类没有主构造函数,那样每个辅助构造函数必须要初始化基类的构造,使用super关键字,不同的辅助构造函数可以初始化基类不同的构造方法。形如:
class MyView : View {
constructor(ctx: Context) : super(ctx) {
}
constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs) {
}
}
这个open注解和final相反,它允许被继承。默认是final类型
open class Base {
open fun v() {}
fun nv() {}
}
class Derived() : Base() {
override fun v() {}
}
一个类的方法用了override,说明它自己是open,这个类的子类还可以覆盖这个方法。如果不想让它覆盖则在前面声明final类型。形如:
open class AnotherDerived() : Base() {
final override fun v() {}
}
open class A {
open fun f() { print("A") }
fun a() { print("a") }
}
interface B {
fun f() { print("B") } // interface members are 'open' by default
fun b() { print("b") }
}
class C() : A(), B {
// The compiler requires f() to be overridden:
override fun f() {
super.f() // call to A.f()
super.f() // call to B.f()
}
}
open class Base {
open fun f() {}
}
abstract class Derived : Base() {
override abstract fun f()
}
sealed class Expr {
class Const(val number: Double) : Expr()
class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
}
fun eval(expr: Expr): Double = when(expr) {
is Const -> expr.number
is Sum -> eval(expr.e1) + eval(expr.e2)
NotANumber -> Double.NaN
// the `else` clause is not required because we've covered all the cases
}