Kotlin Class, object, and interfaces
Kotlin中的接口:interface关键字 不同于java方法的implement和extends,kotlin使用的是冒号: 来完成这个方法。 也不同与java的注释override,我们使用关键词override来强制实现。
接口默认实现:
interface Clickable{fun click() // 方法声明fun showOff() = println("i am clickable") // 接口默认实现
}
复制代码
对于接口默认实现的方法:
- 我们可以直接使用
- 我们也可以重写这个方法
interface Focusable{fun setFocus(b: boolean) = println("I ${if(b) "got" else "Losr"} focus")fun showOff() = println("i'm foucusable! ")
}
复制代码
如果一个类实现了多个接口,而多个接口却有相同的方法,我们需要具体指定实现哪一个方法
class Button: Clickable, Focusable{override fun click() = println("I was clicked")override fun showOff(){super<Clickable>.showOff()super<Focusable>.showOff()}
}
复制代码
final by default
kotlin中的类默认都是final ,在Effective java中提到了一点:『design and document for inheritance or else prohibit it』
// 这个类可以被其他类继承
open class RichButton: Clickable {fun disable(){} // fun 默认是final 表示这个方法可以被复写open fun animate(){} // open fun 表示你可以复写这个方法override fun click(){} // 这个方法复写一个open fun 它同样也是open fun 可以被人复写final override fun click1(){} // 但是被final修饰了 所以不可以被其他复写
}
复制代码
abstract
和java一样 abstract表示的是这个类不可以被实例化,一个抽象类可以包含抽象对象和抽象方法,抽象类中的所有的方法都是open
abstract class Animated{abstract fun animate()open fun stopAnimating(){}fun animateTwice(){}
}
复制代码
modifier | corresponding member | Comments |
---|---|---|
final | can't be overridden | Used by default |
open | Can be overridden | Should be specified |
Abstract | Must be overridden | Can be used only in abstract class |
override | overrides a member in superclass | Overrideen member is open by default if not marked final |
pubic by default
kotlin只有三个标识修饰关键字:public protected private。 去掉了java中的package-private,在Kotlin中packages只是在namespace中来组织代码而已。
modifier | class member | Top-level declaration |
---|---|---|
public | visible everywhere | Visible everywhere |
Protected | visible in subclassed | |
private | visible in a class | visible in a file |
Inner And nested class: nested by default
Kotlin中的嵌套类不能访问外部类的对象实例,
interface State : Serializable
interface View{fun getCurrentState() : Statefun restoreState(state: State){}
}public class Button implements View{public State getCurrentState(){return new ButtonState();}public void restoreState(State state){}public class ButtonState implement State{}
}
复制代码
在很多常见的场景,我们都需要创建一个内部类来存储外部类的状态,在上面的代码中当我们调用getCurrentState()来序列化我们会报错,因为这里面有一个问题便是 内部类ButtonState实现了State这个可以序列化的同时其实它还隐藏的持有了外部类的引用 因为Button没有实现序列化的接口导致报错。
class A declared whthin another class B | In Java | In Kotlin |
---|---|---|
Nested class | State class A | class A |
Inner class | class A | Inner class A |
sealed 关键字
我们都知道enum枚举 表示有限的集合,但是enum对应的其实是基本数据类型。在kotlin中类的表达其实是sealed,两者高度相似。
类中的constructor
kotlin中的构造函数分为两种,因为kotlin中允许可以默认参数 所以kotlin的写法中不太需要过载方法 一般只需要设置一些默认参数就可以
// kotlin中的原创写法 简洁不少 去掉了constructor 同时不用申明变量
class User(val nickName: String)// 想java一种使用关键词constructor init super this
class User constructor(_nickname: String){val nickname:String//此处初始化可以多次使用 按照声明的顺序按顺序执行init{nickname = _nickname}init{nick}
}class MyButton : View{constructor(ctx: Context):super(ctx){}
}复制代码
interface中的变量
interface User{val nickName: String
}
复制代码
接口中的声明的变量如何去初始化
class PrivateUser(override val nickname:String) :Userclass SubscribeingUser(val email: String) : User{override val nickname;Stringget() = email.substringbefore('@')
}class FaceBookUser(val accountId: Int) : User{override val nickname = getFacebookName(accountId)
}
复制代码
类的装饰模式 by 关键字
class DelegatingCollection<T>(innerList: Collection<T> = ArrayList<T>()):Collection<T> by innerList
复制代码
类的单例模式 object 关键字
- 类的单例模式
object Payroll{val allEmployees = arrayListOf<Person>()fun calculateSalary(){for(person in allEmployees){}}
}
复制代码
object 中的对象没有所谓的构造器,对象的生成在定义的时候就会立即生成,而不是通过偶在函数来生成的
object的对象的调用之间使用 . 即可,这一点和javascript中的字面对象有点像
Payroll.allEmployees.add(Person(...))
Payroll.calculateSalary()
复制代码
Object 对象也可以被类继承和接口实现。
-
Static 静态方法和对象
直接创建一个工厂模式 也就是所谓的静态方法
class User(val nickname: String){companion object{fun newBeginingUser(email:String) = User("")fun newFacebookUser(accountId: Int) = User(account)} } 复制代码
使用方法:
val subscribeingUser = User.newBeginingUser("bob@email.com") val facebookUser = User.newFacebookUser(3) 复制代码
-
匿名内部类
Object可以充当一个匿名内部类来使用
window.addMouselistener(object: MouseAdapter(){... }) 复制代码
Summary
- Interface 在Kotlin中和Java类似 除了可以拥有默认的方法实现和属性
- 所有的声明默认都是 final public
- 想让声明不是final 需要使用关键open
- Nested class 默认是不外部类有引用关系, 可以使用关键字 inner 来内部类与外部类有引用关系
- 关键字 sealed 可以将有限的子类包含在父类中(在when 中可以去掉else 因为包含了所有的可能性)
- 除了 第一构造函数外,我们还有 init constructor 来灵活初始化对象
- field 可以提供便捷的对象的set() get()方法的使用
- data 也就是所谓的Javabean 关键字可以提供 equals hashCode toString copy 等便捷的方法
- by 关键字可以提供类似代理模式
- object 关键字 可以提供单例模式
- companion object 替代了java所有的静态方法和属性定义
- object 关键字可以替代java中的匿名内部类