实现接口
interface Clickable{
//类似Java8默认方法
fun showOff() = println("I was clickable")
//要自己实现
fun click()
}
interface Focusable{
//可以直接使用
fun setFocus(b: Boolean) =
println("I ${if (b) "got" else "lose"} focus")
fun showOff() = println("I was focused")
}
class Button : Clickable, Focusable {
//两个接口都有这个方法,必须重写
override fun showOff() {
super<Clickable>.showOff()
super<Focusable>.showOff()
}
override fun click() {
println("i was a button")
}
}
open关键字
Kotlin默认类都是public final的
可继承的类和方法必须声明open
open class RichButton : Clickable{
//默认是不可重写
fun disable() {}
//可以被重写
open fun animate(){}
//覆盖接口的方法,默认也可以重写
//不想被重写,可以加上final
override fun click() {}
}
abstract关键字
abstract class Animated {
//必须覆盖
abstract fun animate()
open fun stopAnimating() {}
fun animateTwice() {}
}
访问修饰
internal open class TalkativeButton : Focusable {
private fun yell() = println("Hey!")
protected fun whisper() = println("Let's talk!")
}
fun TalkativeButton.giveSpeech() {//报错
yell() //报错
whisper() //报错
}
内部类的实现
/* Java */
//因为这个ButtonState类保存一个指向外部的作用域
//所以不能序列化ButtonState,因为Button不能被序列化
public class Button implements View {
@Override
public State getCurrentState(){
return new ButtonState();
}
@Override
public void restoreState(State state) { /*...*/ }
public class ButtonState implements State,Serializable { /*...*/ }
}
class Button : View {
override fun getCurrentState(): State = ButtonState()
override fun restoreState(state: State) { /*...*/ }
class ButtonState : State { /*...*/ }
}
class Outer {
inner class Inner {
//指向外部作用域
fun getOuterReference(): Outer = this@Outer
}
}
sealed关键字
限定地创建子类,除了sealed类作用域里面的子类以外,不能创建别的子类
sealed class Expr {
class Num(val value: Int) : Expr()
class Sum(val left: Expr, val right: Expr) : Expr()
}
fun eval(e: Expr): Int =
when (e) {
is Expr.Num -> e.value
is Expr.Sum -> eval(e.right) + eval(e.left)
}
默认构造器
class User(val nickname: String)
//完整写法
class User constructor(_nickname: String){
val nickname: String
init {
nickname = _nickname
}
}
私有构造器
class Secretive private constructor() {}
class Secretive {
private constructor()
}
次级构造器
open class View {
constructor(ctx: Context) {
// some code
}
constructor(ctx: Context, attr: AttributeSet) {
// some code
}
}
子类调用父类构造器
open class View {
constructor(ctx: Context) {
// some code
}
constructor(ctx: Context, attr: AttributeSet) {
// some code
}
}
class MyButton : View {
constructor(ctx: Context) : super(ctx) {
// ...
}
constructor(ctx: Context, attr: AttributeSet) : super(ctx, attr) {
// ...
}
}
class MyButton : View {
constructor(ctx: Context): this(ctx, MY_STYLE) {
// ...
}
constructor(ctx: Context, attr: AttributeSet): super(ctx, attr) {
// ...
}
}
属性覆盖
interface User {
val nickname: String
}
class PrivateUser(override val nickname: String) : User
class SubscribingUser(val email: String) : User {
override val nickname: String
get() = email.substringBefore('@')
}
class FacebookUser(val accountId: Int) : User {
override val nickname =
getFacebookName(accountId)
}
data class
data class会自动重写toString(), equals(), hashCode()方法。
==是equals()的语法糖
===和Java中的==是一样的,比较是不是一个对象
代理类–by关键字
使用简化代理类,可以只重写需要的方法,不想重写的方法,会自动代理给代理对象
//复杂的代理类写法
class DelegatingCollection<T> : Collection<T>{
private val innerList = arrayListOf<T>()
override val size: Int
get() = innerList.size
override fun contains(element: T): Boolean = innerList.contains(element)
override fun containsAll(elements: Collection<T>): Boolean = innerList.containsAll(elements)
override fun isEmpty(): Boolean = innerList.isEmpty()
override fun iterator(): Iterator<T> = innerList.iterator()
}
//简化代理类
class DelegatingCollection<T> (
innerList: Collection<T> = ArrayList<T>()
) : Collection<T> by innerList
object单例对象
想想javascript的对象就懂了
data class Person(val name: String)
object Payroll{
val allEmployees = arrayListOf<Person>()
fun calculateSalary(){
for (person in allEmployees){
println(person.name)
}
}
}
伴生对象:代替工厂方法和静态方法
其实是有个隐含的Companion对象
//静态方法
class A {
companion object{
fun bar(){
println("Companion object called")
}
}
}
fun main(vararg args: String){
A.bar()
}
//工厂方法
class User2(val nickname: String){
companion object{
fun newSubscribingUser(email: String){
User2(email.substringBefore('@'))
}
fun newFacebookUser(accountId: Int){
User2(accountId.toString())
}
}
}
fun main(vararg args: String){
User2.newFacebookUser(1111)
User2.newSubscribingUser("qwqw@qq.com")
User2.Companion.newSubscribingUser(...)
}
匿名对象
Java内的匿名内部类
window.addMouseListener(
object: MouseAdapter(){
override fun click(e: MouseEvent){
//....
}
}
)