Kotlin的接口与Java8中类似,它们能够包含抽象方法的定义以及非抽象方法的实现,但它们不能包含任何状态。dom
1 interface Clickable{ 2 fun click() 3 fun showoff()=println("It's show time!") 4 } 5 6 interface Focusable{ 7 fun setFocus(b: Boolean)= 8 println("I ${if (b) "got" else "lost"} focus.") 9 fun showoff()= println("Kotlin") 10 } 11 12 class Button: Clickable, Focusable{ 13 //override用法同Java@Override但为强制要求 14 override fun click() { 15 println("I was clicked!") 16 } 17 18 //这里若是没有显示地实现showoff,会获得编译错误 19 override fun showoff(){ 20 //Java中的用法:Clickable.super.showoff(); 21 /*super<Clickable>.showoff() 22 super<Focusable>.showoff()*/ 23 println("Method of son.") 24 } 25 }
1 /** 2 * Java中的类和方法默认是open的,而Kotlin中默认是final的。 3 * 若是你想容许一个类建立一个子类,须要使用open修饰符来标识这个类 4 * 方法与属性也是如此。 5 * */ 6 open class Button: Clickable{ 7 //这个函数是open的 8 override fun click() { 9 println("Clicking it") 10 } 11 //这个函数再也不是open的了 12 final override fun showoff()= println("Show off") 13 open fun animate(){} 14 } 15 16 /** 17 * abstract类与Java中的相同,不能被实例化。 18 * 19 * */ 20 abstract class Animated{ 21 //这个函数是抽象的,必须被子类实现,因此也是open的 22 abstract fun animated() 23 24 //抽象类中的非抽象函数并非默认open的,但能够标注为open的 25 open fun stopAnimating()= println("Stop it!") 26 }
可见性修饰符帮助控制对代码库中声明的访问。Java中默承认见性为-----包私有,在Kotlin只把包做为在命名空间里组织代码的一种方式使用,并无将其用做可见性控制。ide
做为替代Kotlin中提供了一种新的修饰符---internal,表示"只在模块(一组一块儿编译的Kotlin文件)内部可见"。另一个区别就是Kotlin容许在顶层声明中使用private可见性,函数
使这些声明只会在声明他们的文件中可见。post
1 open internal class Button{ 2 private fun click()= println("Hey!") 3 protected fun showoff()= println("show it") 4 } 5 6 /* 7 fun Button.fMethod(){ //错误:public成员暴露了其"internal"接收者类型B 8 yell() //错误 9 showoff() //错误 10 } 11 */ 12 13 internal fun Button.fMethod(){ 14 /*showoff() 任然错误*/ 15 }
另外一个与Java可见性不一样的是:一个外部类不能看到其内部类或嵌套类中的private成员。this
只须要记住Kotlin中没有显示修饰符的嵌套类与Java中的static嵌套类是同样的,若是要使其持有外部类的引用的话须要使用inner修饰符。spa
引用外部类实例语法:this@outercode
为父类添加一个sealed修饰符,对可能建立的子类作出严格限制,全部的直接子类必须嵌套在父类中。对象
请思考这样作的好处。blog
1 class User0(val name: String="tang"/*可提供默认值*/) /*简便写法,其中val关键字意味着 2 相应的属性会用构造方法的参数来初始化*/ 3 4 open class User constructor(name: String)/*带参数的主构造方法,constructor 5 用来声明一个主构造方法和一个从构造方法*/{ 6 val name:String 7 8 init { //初始化语句块,由于主构造方法的语法限制,全部有了初始化语句 9 //一个类中能够声明多个初始化语句 10 this.name=name 11 } 12 } 13 14 //若是一个类具备父类,主构造方法一样须要初始化父类。 15 // 即便父类构造函数没有任何参数,也要显示地调用构造函数。 16 class TwitterUser(name: String) : User(name){} 17 18 //若是要确保类不被实例化,能够把构造函数标记为private 19 class Person private constructor(val name: String)
1 //没有主构造函数 2 open class View{ 3 constructor(ctx: String) 4 constructor(ctx: String, attr: String) 5 } 6 7 class MyButton : View{ 8 constructor(ctx: String) :this(ctx,"s") 9 10 constructor(ctx: String,attr: String) : super(ctx,attr){ 11 /*some code*/ 12 } 13 }
1 /*接口能够包含抽象属性声明*/ 2 interface User{ 3 val nickname: String 4 /*接口还可包含具备getter和setter的属性,只要他们没有引用一个支持字段*/ 5 val age: Int 6 get() = Random().nextInt(100) 7 } 8 9 /*在实现了接口的类中必须override该属性*/ 10 class QQUser (override val nickname: String) : User 11 12 class BaiduUser(val email: String) : User{ 13 override val nickname: String 14 get() = "Baidu $email" 15 }
1 class User(val name: String){ 2 var address: String="unspecified" 3 //在set函数体中,使用了标识符field来访问支持字段的值。 4 //在get函数中只能读取它,在set函数中能够修改它。 5 set(value: String) { 6 println(""" 7 Address was changed for $name: "$field" -> "$value".""".trimIndent()) 8 } 9 } 10 11 fun main(args: Array<String>) { 12 val user=User("Tom") 13 user.address="Back Street 221" 14 user.address="Beijing hu tong 222" 15 /*Address was changed for Tom: "unspecified" -> "Back Street 221". 16 Address was changed for Tom: "unspecified" -> "Beijing hu tong 222".*/ 17 18 }
1 class LengthCounter{ 2 var counter: Int=0 3 private set //声明为private,不能再类外部修改这个属性 4 5 fun addWord(word: String){ 6 counter+=word.length 7 } 8 }
1.toString()继承
2.equals():在Kotlin中"=="至关于Java中的equals,"==="至关于Java中的"=="(比较引用)
3.hashCode()方法一般与equals方法一块儿被重写(若是两个对象相等,它们一般必须有相同的hash值)。
1 class Client(val name: String,val postalCode: Int){ 2 override fun equals(other: Any?): Boolean { 3 if (other==null || other !is Client) return false 4 return name==other.name && postalCode==other.postalCode 5 } 6 7 override fun toString(): String { 8 return "Client($name,$postalCode)" 9 } 10 11 override fun hashCode(): Int { 12 return name.hashCode()*12+postalCode 13 } 14 }
若是为类添加data修饰符,上述通用方法将会被自动生成好。其中
1.equals方法:检测因此主构造函数属性的值是否相等。
2.hashCode方法:返回一个根据全部主构造函数中属性值生成的哈希值。
注意:没有在主构造函数中声明的属性将不会加入到相等性检测和哈希值计算中去。
data class User(val name: String,val age:Int,val gender: String)
class TangCollection<T>( val innerList: Collection<T> = ArrayList<T>() ) : Collection<T> by innerList {}
object关键字:定义一个类的同时建立一个实例
/* * 在定义的时候就被建立,而且为一个单例 * */ object User { val name: String = "Tang" val age: Int = 8 }
class A { companion object { fun t(){ println("Tang") } } } fun main(args: Array<String>) { A.t() }