隔了好久又开始写了
最近开始kotlin学习就顺便记一下
编译器用的IntelliJ环境搭建过程不记录了
可能会多处与java对比
声明包
package swu.cjy
import kotlin.*
输出语句
println("Hello world")//换行
print("Hello world")//不换行
输出变量
val name = "ciel"
println(name)
val name = "ciel"
println("name is $name")
val name = "ciel"
println("name is $name length is ${name.length}")
程序入口
fun main(){
println("Hello world!")
}
定义变量
val 定义常量
var 定义变量
val pi: Double = 3.14
val name="辞"
//可不指定类型 类型自动推导
var temp = 20
var score=95.5
temp = 30
temp = score//错误
temp = score.toInt()//正确
kotlin类型不一致时不能赋值,需要使用to()方法进行显示转换,java中精度小的可以给精度大的赋值,精度大的需要强制转换后才能赋值
基本数据类型
类型 | 位宽度 |
---|---|
Double | 64 |
Float | 32 |
Long | 64 |
Int | 32 |
Short | 16 |
Byte | 8 |
Char
Kotlin 中的 Char 不能直接和数字操作,Char 必需是单引号 ' 包含起来的。比如普通字符 '0','a'
Boolean
布尔用 Boolean 类型表示,它有两个值:true 和 false。
若需要可空引用布尔会被装箱。
内置的布尔运算有:
|| 短路逻辑或
&& 短路逻辑与
! 逻辑非
Array
数组用类 Array 实现,并且还有一个 size 属性及 get 和 set 方法,由于使用 [] 重载了 get 和 set 方法
数组的创建两种方式:一种是使用函数arrayOf();另外一种是使用工厂函数。
String
Kotlin 支持三个引号 """ 扩起来的字符串,支持多行字符串
String 可以通过 trimMargin() 方法来删除多余的空白,默认 | 用作边界前缀,但你可以选择其他字符并作为参数传入,比如 trimMargin(">")
条件控制
if
Kotlin中if-else是一个表达式->结果
val res = if (num > 10) "下载成功" else "下载失败"
val res = if (num > 10) 20 else "下载失败"
区间
if ( x in 1..8){
println("x在区间内")
}
elvis操作符
java中有着问号表达式
2 > 1 ? a:b
在kotlin中?:
如果左侧的值为空,就取右侧的值
val emails = …… // 可能会是空集合
val mainEmail = emails.firstOrNull() ?: ""
when
when (x) {
1 -> print("x = 1")
2 -> print("x = 2")
else -> { // 注意这可以是一个块
print("x 不是 1 ,也不是 2")
}
}
循环
for
for ( i in 1..10){
//包括10
}
for ( i in 1 until 10){
//不包括10
}
for (i in 1..10 step 2){
//跨两步
}
for (i in 10 downTo 1){
//降序
}
val array = arrayOf("a","b","c")
for (i in names){
//直接取出
}
for (i in array.indices){
//通过索引取出
println(array[i])
}
for ((index,item) in names.withIndex()){
//同时取出索引和内容
}
while
while(){
}
do{
}while()
返回和跳转
1.return 默认从最直接包围它的函数或者匿名函数返回。
2.break 终止最直接包围它的循环
3.continue 继续下一次最直接包围它的循环
输入
readLine()
//返回值字符串
如果想读其他类型 需要使用scanner
val reader = Scanner(System.'in')
//会导入 java.util.Scanner这个包
var enteredValue:Int = reader.nextInt()
类
构造函数
kotlin中构造函数分两种
1.主构造函数 类的头部
2.次构造函数 类的内部 可多个
次构造函数必须显式调用主构造函数
class Person{
//默认提供一个没有参数的构造函数Person() 这算是主构造函数
}
//以下两种方式也行
class Person(){
}
class Person constructor(){
//当有修饰的时候constructor不能省略,如private
}
//提供一个次构造函数
class Person(){
constructor(name:String):this(){
}
constructor(name: String,age: Int):this(){
}
}
有参数构造方法
1.主构造函数
参数是局部变量,外部无法访问
只有对象初始化(创建对象/Init)的方法里面可以访问
class Car(brand: String){
val myBrand = brand
init{
println(brand)
}
}
2.次构造函数
class Car(brand: String){
init{
println(brand)
}
constructor(brand: String, color: String):this(brand){
}
}
参数属性化并提供默认值
class Student(var name:String){
}
class Student(var name:String="辞”){
}
继承
kotlin中类默认不能被继承
必须使用open而且只能单继承
可以间接继承
open class Animal(){
}
open class Father():Animal(){
}
class Child() : Father(){
}
有参
open class Father(name: String){
}
class Child(name: String) : Father(name){
}
重写方法
默认情况下方法不能被重写 必须父类中方法open 子类中override修饰
多态
为了统一接口
在父类中成员变量和成员函数被子类继承之后,可以具有不同的状态或表现行 为
发生多态的条件
- 继承。多态发生一定要子类和父类之间。
- 重写。子类重写了父类的函数。
- 声明对象类型是父类类型,对象是子类的实例。
属性的set-get函数
默认定义属性时会自动创建对应的set get方法
val 常量 只有get
var 变量 有set和get
kotlin类的属性声明的同时必须初始化
可以重写默认的set get方法
默认情况下任何一个属性都有一个内部变量 field 相当于是值的域 这个变量只在初始化的时候调用get/set
var|val 属性名 [ : 数据类型] [= 属性初始化 ]
[getter]
[setter]
可空类型
1.声明变量不知道是否非空
2.接收java返回值
?
如果这个对象为空 则后面不会执行
不为空则执行对应方法
val girlfriend: String? = null
println(girlfriend?.length)
!! 非空
val girlfriend: String? = "ciel"
println(girlfriend!!.length)
延迟加载和懒加载
延迟加载
必须在某个时候(调用之前)初始化
lateinit var imgdata: String
懒加载
访问的时候才会加载值(调用时才被初始化)
val data: String by lazy{
"数据"
}
普通函数
//Unit == void
fun buy(money: Int):Unit{
}
fun study(money: Int): Int{
//...
return 123456
}
fun add(a: Int, b: Int): Int{
return a+b
}
fun add(a: Int, b: Int) = a + b
传可变参数要使用vararg修饰
fun add(vararg num:Int){
var result = 0
for(value in num){
result +=value
}
println(result)
}
局部函数 local function
函数内部还能定义函数
fun showView(){
fun loadData(){}
fun showList(){
val mg=loadData()
println(mg)
}
showList()
}
数据类Data Class
类似java中的数据模型
要求
1.数据类的主构造函数必须至少有一个参数
2.参数必须使用var或者val修饰(属性化)
3.不能使用open inner abstract修饰
嵌套类Nested Class
类似java的静态方法
类可以嵌套在其他类中
是独立的 不能访问宿主类的属性和方法
使用
Bank.Money()
内部类Inner Class
类可以标记为inner以便能够访问外部类的成员。内部类会带有一个对外部类的对象的引用。
使用
Bank().Money()
匿名内部类
object
window.addMouseListener(object: MouseAdapter(){
override fun mouseClicked(e: MouseEvent) { // ……
}
override fun mouseEntered(e: MouseEvent) { // ……
"'}
}
抽象类Abstact Class
abstract
class Figure {
//绘制几何图形函数
abstract fun onDraw() //抽象函数
abstract val name: String //抽象属性
val cname: String = "几何图形" //具体属性
fun display() {//具体函数
println(name) }
}
抽象类里面可以定义
1.抽象属性 不能初始化
2.抽象方法 不能实现
3.普通方法
如果是子类必须实现 那么就定义为抽象方法 否则定义为普通方法
抽象类默认是open的
如果要重写抽象类的方法 必须使用open来修饰