kotlinclass

kotlin class

结构 & 构造方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//默认是final,添加open表示非final,可以继承
//主构造方法,不建议这么写,有主构造方法时子类无法调用次要构造方法
//[open ][public] class DataUser [constructor]()
open class DataUser constructor(name : String) {
init {
//初始化-在super()之后调用
println("1:"+System.nanoTime())
}
// : this() 调用自身构造方法
//次要构造方法
//constructor([name : TypeName]*) : this([name : TypeName]*)
constructor(name: String , age : Int,parent: DataUser) : this(name){
//在init之后调用
println("0:"+System.nanoTime())
}
}
class ChildUser(name: String): DataUser(name) {
// 子类只能调用父类主构造方法
// constructor(name: String, age : Int) : super(name, age)
}
kotlin 有一个主构造方法多个次要构造方法,子类构造方法无法使用父类次要构造方法

open –> 去掉final

1
2
3
4
5
//在class上添加,允许继承
open class DataUser{
//在方法上添加,允许重写,重写需要加override
open fun noFinal(){}
}

构造方法 & 继承

1
2
3
4
5
6
7
8
open class DataUser {
constructor(name: String) : this(name)
constructor(name: String , age : Int,parent: DataUser) : this(name)
}
class ChildUser : DataUsers{
constructor(name: String) : super(name)
constructor(name: String , age : Int,parent: DataUser) : super(name)
}

重写父类方法

1
2
3
4
5
6
7
8
9
//继承
class SuperClass {
open fun get()
}
class ChildClass : SuperClass {
// 重写必须带override
override fun get()
}

自欺欺人的属性覆盖

1
2
3
4
5
6
7
8
9
10
//实际上编译之后属性并没有改变,只是复写了get方法,覆盖了get,不信你用super.x试试
interface Foo {
val count: Int
}
class Bar1(override val count: Int) : Foo
class Bar2 : Foo {
override var count: Int = 0
}

接口

1
2
3
4
5
6
7
//方法可以有默认实现,实际是写了默认实现类
interface Foo {
fun f()
fun b(){
printlb("default")
}
}

枚举

1
2
3
4
5
6
//定义和java一样
enum class Direction {
NORTH, SOUTH, WEST, EAST
}
//EemuClass.valueOf("NORTH")
var dir = Direction.valueOf("NORTH")

多继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
open class A {
open fun f() { print("A") }
fun a() { print("a") }
}
interface B {
fun f() { print("B") } // 接口的成员默认是 'open' 的
fun b() { print("b") }
}
class C() : A(), B {
// 编译器要求 f() 方法必须覆盖:
override fun f() {
super<A>.f() // 调用 A.f()
super<B>.f() // 调用 B.f()
}
}

单例 –>通过伴生对象实现

1
2
3
4
5
6
7
8
9
10
11
12
//使用伴生对象
class Singlton private constructor(){
companion object {
val INSTANCE = Singlton()
}
}
//使用object表达式
object Inner2 : Inner{
override fun action() {
}
}

匿名内部类 –> object : ClassName construstor()

1
2
3
4
5
6
7
8
9
10
11
fun main(args: Array<String>) {
var inner : Inner = object : Inner{
override fun action() {
println("action");
}
}
inner.action()
}
interface Inner{
fun action()
}

封闭类(Sealed Class)

1
2
3
4
5
6
7
8
9
10
11
12
//== abstract + [private constructor]
//可以使用内部
sealed class name{
constructor(){
print(1)
}
//非static
var a : String? = null
//public static final
class Const : SealedTest()
class Const2 : SealedTest()
}

伴生类 (companion object)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//会生成一个public static final class Companion,并且构造方法私有化
class Test{
// Test会持有一个public static final Companion对象
companion object {
//属性会外提到Test
const val i = 1;
var j = 2;
fun get() : Int = 3
}
fun main(){
println(i)
//实际是调用Companion对象的.getJ()
println(j)
println(get())
}
}

权限

1
2
3
4
5
在top-level,包括包名名下
如果你不指定任何可见度修饰符, 默认会使用 public, 其含义是, 你声明的东西在任何位置都可以访问;
如果你将声明的东西标记为 private, 那么它将只在同一个源代码文件内可以访问;
如果标记为 internal, 那么它将在同一个模块(module)内的任何位置都可以访问;
对于顶级(top-level)声明, protected 修饰符是无效的.
1
2
3
4
5
private class PrivateTest{}
open class ProtectedTest{}
internal class InternalTest{}
public class PublicTest{}
class DefaultTest{}
1
2
3
4
5
在class和interface内
private 表示只在这个类(以及它的所有成员)之内可以访问;
protected — 与 private 一样, 另外在子类中也可以访问;
internal — 在 本模块之内, 凡是能够访问到这个类的地方, 同时也能访问到这个类的 internal 成员;
public — 凡是能够访问到这个类的地方, 同时也能访问这个类的 public 成员.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
open class Outer {
private val a = 1
protected open val b = 2
internal val c = 3
val d = 4 // 默认为 public
protected class Nested {
public val e: Int = 5
}
}
class Subclass : Outer() {
// a 不可访问
// b, c 和 d 可以访问
// Nested 和 e 可以访问
override val b = 5 // 'b' 可见度为 protected
}
class Unrelated(o: Outer) {
// o.a, o.b 不可访问
// o.c 和 o.d 可以访问(属于同一模块)
// Outer.Nested 不可访问, Nested::e 也不可访问
}

扩展函数

1
2
3
4
5
//实际操作是底层持有了调用的对象
fun TpyeName.method(){}
//demo== int add(int $receiver, int other)
//加?表示可空
fun Int?.add(other : Int): Int{}

扩展属性(Extension Property)

1
2
3
4
//实际操作是底层持有了调用的对象,实际也是添加了get方法
// 对于扩展属性不允许存在初始化器
val <T> List<T>?.lastIndex: Int
get() = size - 1

对象表达式 –>用于函数内,立即执行

1
2
3
4
5
6
7
8
9
10
11
//1、匿名内部类 object className demo在上面
var inner : Inner = object : Inner{
override fun action() {
println("action")
}
}
//2、 不写基类默认基础object
val adHoc = object {
var x: Int = 0
var y: Int = 0
}

对象声明 –>用户方法外,延迟执行

1
2
3
4
5
6
7
8
9
10
11
12
//对象申明都是单例,并且直接使用类名就会自动调用单例对象
//比如 Adapter.setData() 实际调用Adapter.INSTANCE.setData()
//对象声明:调用到才会初始化
object Adapter {
fun setData() {}
var count:Int = 0
}
//对象申明可以继承和实现类,但是最后基类不要有主要构造,或者主要构造中不需要传值
object Inner2 : Inner{
override fun action() {
}
}

类委托

1
2
3
4
5
6
7
8
9
10
11
12
13
//Derived 实现了Base,并将事情委托给BaseImpl2
interface Base {
fun print()
}
class BaseImpl2(val x: Int) : Base {
override fun print() { print(x) }
}
class Derived(b: Base) : Base by b
fun main(args: Array<String>) {
val b = BaseImpl2(10)
Derived(b).print() // 打印结果为: 10
}

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器