Code Kotlin学习笔记0x05

面向对象编程

类与构造函数

声明类

和大部分语言类似,Kotlin使用class作为关键字

1
class World

这样我们就声明了一个World类

构造函数

在Kotlin中一个类只能有一个主构造函数和至少一个的次构造函数

1
open class Student constructor(var name: String, var age: Int):Any(){}

与普通属性一样,主构造函数中声明类型的属性是可变(var)或只读(val)的
主构造函数中不能包含任何的代码,初始化的代码需要放到以init关键字作为前缀的初始化块中

1
2
3
4
5
open class Student constructor(var name: String, var age: Int):Any(){
init{
println("Student{name=$name,age=$age} created!")
}
}

次构造函数
在类体中,我们也可以声明前缀有constructor的次构造函数,次构造函数不能有声明val,var:

1
2
3
class MiddleSchoolStudent{
constructor(name: String, age: Int){}
}

如果类有一个主构造函数,那么每个次构造函数需要委托给主构造函数,委托到同一个类的另外一个构造函数用this关键字即可

1
2
3
4
5
6
class ElementartSchoolStudent public @MyAutowired constructor(name:String, age: Int):Student(name, age){
override var weight: Float = 80.0f
constructor(name: String, age: Int, weight: Float):this(name,age){
this.weight = weight
}
}

类的属性

1
2
3
4
class World1 {
var yin: Int = 0
var yang: Int = 1
}

类的属性必须要进行初始化,如果不初始化就得是抽象属性

类函数

1
2
3
4
5
6
7
8
class World2 {
var yin: Int = 0
var yang: Int = 1
//下面就是一个类函数
fun plus():Int{
return yin + yang
}
}

抽象类

抽象类的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
abstract class Person(var name: String,var age: Int):Any(){
abstract var addr: String
abstract var weight: Float

abstract fun doEat()
abstract fun doWalk()

fun doSwim(){
printlin("I'm Swimming...")
}

open fun doSleep(){
println("I'm Sleeping...")
}
}

抽象类不能用来创建对象实例.

抽象函数

上面的doEat和doWalk就是两个抽象函数,抽象函数在抽象类中并没有具体的实现,抽象函数默认是public的
doSwim并不是抽象函数,被默认为了final,因此无法被重写,而doSleep函数可以被重写,因为他有open关键字

抽象属性

addr和weight就是两个抽象属性,她不能在抽象类中被初始化


接口

与java类似,Kotlin也使用interface作为接口的关键字
Kotlin中只可以继承一个类,但是可以实现多个接口
实现方法是通过冒号:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
fun main(args: Array<String>) {
var pmsi: ProjectMilestoneServiceImpl = ProjectMilestoneServiceImpl()
pmsi.print()
}
//声明了两个空壳类
class Project
class Milestone

interface ProjectService{
val name: String
val owner: String
//ProjectService的save函数
fun save(project: Project)
fun print(){
println("I am project")
}
}

interface MilestoneService{
val name:String
//MilestoneService的save函数
fun save(milestone: Milestone)
fun print(){
println("I am Milestone")
}
}

class ProjectMilestoneServiceImpl:ProjectService,MilestoneService{
//重载了name
override val name: String
get() = "ProjectMilestone"
//冲在了owner
override val owner: String
get() = "Jack"
//对ProjectService中的save函数进行重载
override fun save(project: Project){
println("Save Project")
}
//对print进行重载
override fun print(){
// 指出具体调用那一个接口中的print方法
super<ProjectService>.print()
super<MilestoneService>.print()
}
//对MilestoneService中的save函数进行重载
override fun save(milestone: Milestone){
println("Save Milestone")
}
}

输出结果

1
2
I am project
I am Milestone

接口主要是对动作的抽象,定义了行为特性的规约。 抽象类是对根源的抽象。当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。—–Kotlin极简教程


枚举类

1
2
3
4
5
6
7
8
9
10
11
fun main(args: Array<String>){
var size_s = Size.S
println(size_s)
println(size_s.name)
println(size_s.ordinal)
println(size_s is Size)
}

enum class Size{
S,M,L,XL
}

输出结果

1
2
3
4
S
S
0
true

1
2
3
4
5
6
7
8
9
10
11
fun main(args: Array<String>){
var red = Color.RED
print(red.rgb)
//16711680
}

enum class Color(val rgb: Int){
RED(0xFF0000),
GREEN(0x00FF00),
BLUE(0x0000FF)
}

##数据类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
fun main(args: Array<String>){
val book = Book("Book")
println(book.name)
//Book
val jack = User("Jack","Male",1)
println(jack.name)
//Jack
println(jack.gender)
//Male
println(jack.age)
//1
println(jack.toString())
//User(name=Jack, gender=Male, age=1)
println(jack.validate())
//true
}

data class Book(val name: String)
data class Fook(var name: String)
data class User(val name: String,val gender: String,val age: Int){
fun validate():Boolean{
return true
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
fun main(args: Array<String>){
val loginUser = LoginUser("Admin","admin")
println(loginUser.component1())
//Admin 组件一对应name
println(loginUser.component2())
//admin 组件二对应name
println(loginUser.name)
//Admin
println(loginUser.password)
//admin
println(loginUser.toString())
//LoginUser@5305068a
}

open class DBase
interface IBaseA
interface IBaseB

data class LoginUser(val name: String, val password: String):DBase(),IBaseA,IBaseB{
override fun equals(other: Any?):Boolean{
return super.equals(other)
}
override fun hashCode():Int{
return super.hashCode()
}
override fun toString():String{
return super.toString()
}

fun validate():Boolean{
return true
}
}

嵌套类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
fun main(args: Array<String>){
val one = Lv1.Lv2().one
val two = Lv1.Lv2.Lv3().getTwo()
val three = Lv1.Lv2.Lv3.Lv4().three
val four = Lv1.Lv2.Lv3.Lv4().getFour()
println(one)
//1
println(two)
//2
println(three)
//3
println(four)
//4
}

class Lv1{

class Lv2{
private val zero: Int = 0
val one: Int = 1

class Lv3{
fun getTwo() = 2

class Lv4{
val three = 3
fun getFour() = 4
}
}
}
}

普通的嵌套类无法访问外部类的成员
加上inner关键字后即可访问
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
fun main(args: Array<String>){
val innerClass = Lv1.Lv2().Lv3().accessOuter()
//能够成功运行,但是没有任何输出结果,但是按理说应该会输出0和1我尝试在控制台中输入同样的内容,也是没有任何输出结果,至少证明了确实inner类可以访问外部类的内容
}

class Lv1{

class Lv2{
private val zero: Int = 0
val one: Int = 1
inner class Lv3{
fun accessOuter() = {
println(zero)
println(one)
}
}
}
}

类的委托

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import java.util.*

fun main(args: Array<String>){
val subject = RealSubject("World")
subject.hello()
println("-------------------")
val proxySubject = ProxySubject(subject)
proxySubject.hello()
}

interface Subject{
fun hello()
}

class RealSubject(val name: String):Subject{
override fun hello(){
val now = Date()
println("Hello,REAL $name! Now is $now")
}
}

class ProxySubject(val sb: Subject):Subject by sb{
override fun hello(){
print("Before ! Now is ${Date()}")
sb.hello()
print("After 1 Now is ${Date()}")
}
}

输出结果

1
2
3
4
5
Hello,REAL World! Now is Mon Dec 25 14:47:48 UTC 2017
-------------------
Before ! Now is Mon Dec 25 14:47:48 UTC 2017Hello,REAL World! Now is Mon Dec 25 14:47:48 UTC 2017
After 1 Now is Mon Dec 25 14:47:48 UTC 2017

参考资料

在线Kotlin IDE

Kotlin的大部分基础内容到此就结束了,接下来就得看实际开发中的使用了.
现在还是有很多不明白的东西,比如如何创建任意类型的数组.
这些技术债,得慢慢还上.

阅读量: