Android:Kotlin详细入门学习指南-类和对象(下)-基
本人也是在初学Kotlin,如有错误,请帮忙指出,持续更新
Android:Kotlin详细入门学习指南-类和对象(下)-基础语法(五)
建议先看看前面的文章
Android:Kotlin详细入门学习指南-基础语法(一)
Android:Kotlin详细入门学习指南-基本类型-基础语法(二)
Android:Kotlin详细入门学习指南-包-控制流-返回与跳转-基础语法(三)
Android:Kotlin详细入门学习指南-类和对象-基础语法(四)
这篇文章分享的内容比较多,建议先关注收藏,再查看,以免迷路
抽象类
一个类或一些成员可能被声明成 abstract 。一个抽象方法在它的类中没有实现方 法。记住我们不用给一个抽象类或函数添加 open 注解,它默认是带着的。
abstract class Derived : Base() {
override abstract fun f()
}
伴随对象
在 kotlin 中不像 java 或者 C# 它没有静态方法。在大多数情形下,我们建议只用包 级别的函数。
在kotlin中如果我们想直接调用某个方法可以添加@JvmStatic注解也可以使用companion伴生对象,如果想直接使用一个属性,使用@JvmField
class StringUtils{
companion object {
fun isEmpty(str:String):Boolean{
return "".equals(str)
}
}
}
属性和字段
属性声明
在 Kotlin 中类可以有属性,我们可以使用 var 关键字声明可变属性,或者用 val 关 键字声明只读属性。
可以像使用 java 中的字段那样,通过名字直接使用一个属性:
val result = Address() // 在 kotlin 中没有 new 关键字
Getters 和 Setters
语法中的初始化语句,getter 和 setter 都是可选的。如果属性类型可以从初始化语 句或者类的成员函数中推断出来,那么他的类型也是忽略的。
只读属性的声明语法和可变属性的声明语法相比有两点不同: 它以 val 而不是 var 开头,不允许 setter 函数。
编译时常量
那些在编译时就能知道具体值的属性可以使用 const 修饰符标记为 编译时常量
const val SUBSYSTEM_DEPRECATED: String = "This subsystem is depr ecated
延迟初始化属性
这个修饰符只能够被用在类的 var 类型的可变属性定义中,不能用在构造方法中. 并且属性不能有自定义的 getter 和 setter访问器.这个属性的类型必须是非空的,同 样也不能为一个基本类型属性加上 lateinit 修饰符。
接口
Kotlin 的接口很像 java 8。它们都可以包含抽象方法,以及方法的实现。和抽象类 不同的是,接口不能保存状态。可以有属性但必须是抽象的,或者提供访问器的实现。
接口用关键字 interface 来定义:
interface MyInterface {
fun bar()
fun foo() {
//函数体是可选的
}
}
实现接口
一个类或对象可以实现一个或多个接口
class Child : MyInterface {
fun bar () { //函数体
}
}
接口中的属性
可以在接口中申明属性。接口中的属性要么是抽象的,要么提供访问器的实现。接 口属性不可以有后备字段。而且访问器不可以引用它们。
可见性修饰词
类,对象,接口,构造函数,属性以及它们的 setter 方法都可以有可见性修饰词。( getter与对应的属性拥有相同的可见性)。在 Kotlin 中有四种修饰 词: private , protected , internal ,以及 public 。默认的修饰符是 public 。
包
函数,属性和类,对象和接口可以在 "top-level" 声明,即可以直接属于包:
// 文件名: example.kt
package foo
fun baz() {}
class bar {}
- 如果没有指明任何可见性修饰词,默认使用 public ,这意味着你的声明在 任何地方都可见;
- 如果你声明为 private ,则只在包含声明的文件中可见;
- 如果用 internal 声明,则在同一模块中的任何地方可见;
- protected 在 "top-level" 中不可以使用
// 文件名: example.kt
package foo
private fun foo() {} // 在example.kt可见
public var bar: Int = 5 // 属性在认可地方都可见
private set // setter仅在example.kt中可见
internal val baz = 6 // 在同一module中可见
构造函数
通过下面的语法来指定主构造函数(必须显示的使用 constructor 关键字)的可见性:
class C private constructor(a: Int) { ... }
这里构造函数是 private 。所有的构造函数默认是 public ,实际上只要类是可见 的它们就是可见的 (注意 internal 类型的类中的 public 属性只能在同一个模块 内才可以访问)
函数扩展
为了声明一个函数扩展,我们需要在函数前加一个接收者类型作为前缀。下面我们 会为 MutableList<Int> 添加一个 swap 函数:
fun MutableList<Int>.swap(x: Int, y: Int) {
val temp = this[x] // this 对应 list
this[x] = this[y]
this[y] = tmp
}
在扩展函数中的 this 关键字对应接收者对象。现在我们可以在任何 MutableList<Int> 实例中使用这个函数了:
val l = mutableListOf(1, 2, 3)
l.swap(0, 2)// 在 `swap()` 函数中 `this` 持有的值是 `l`
属性扩展
和函数类似, Kotlin 也支持属性扩展:
val <T> List<T>.lastIndex: Int
get() = size-1
注意,由于扩展并不会真正给类添加了成员属性,因此也没有办法让扩展属性拥有 一个备份字段.这也是为什么初始化函数不允许有扩展属性。扩展属性只能够通过明 确提供 getter 和 setter方法来进行定义.
伴随对象扩展
如果一个对象定义了伴随对象,你也可以给伴随对象添加扩展函数或扩展属性:
class MyClass {
companion object {}
}
fun MyClass.Companion.foo(){
}
MyClass.foo()
数据类
和java的bean类似
data class User(val name: String, val age: Int)
泛型
像 java 一样,Kotlin 中的类可以拥有类型参数:
class Box<T>(t: T){
var value = t
}
嵌套类
类可以嵌套在其他类中
class Outer {
private val bar: Int = 1
class Nested {
fun foo() = 2
}
}
val demo = Outer.Nested().foo() //==2
内部类
类可以标记为 inner 这样就可以访问外部类的成员。内部类拥有外部类的一个对象 引用:
class Outer {
private val bar: Int = 1
inner class Inner {
fun foo() = bar
}
}
val demo = Outer().Inner().foo() //==1
匿名内部类
匿名内部类的实例是通过 对象表达式 创建的
window.addMouseListener(object: MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
// ...
}
override fun mouseEntered(e: MouseEvent) { // ...
}
})
对象声明
单例模式是一种很有用的模式,Kotln 中声明它很方便
object DataProviderManager {
fun registerDataProvider(provider: DataProvider) { // ...
}
val allDataProviders: Collection<DataProvider>
get() = // ...
}
DataProviderManager.registerDataProvider(...)
这叫做对象声明,跟在 object 关键字后面是对象名。和变量声明一样,对象声明并 不是表达式,而且不能作为右值用在赋值语句。
伴随对象
在类声明内部可以用 companion 关键字标记对象声明:
class MyClass {
companion object Factory {
fun create(): MyClass = MyClass()
}
}
val instance = MyClass.create()