類
- 定義一個類
使用class
關鍵字
class Person {
}
- 構造函數(shù)
定義的類有一個默認的構造函數(shù),可以在類名后面的大括號中傳入?yún)?shù)
構造函數(shù)的函數(shù)體可以寫在init塊中
class Person(name: String, age: Int) {
init {
}
}
- 創(chuàng)建實例
我們可以像使用普通函數(shù)那樣使用構造函數(shù)創(chuàng)建類實例:
val person = Person("holen", 18) // there's no 'new' keyword in Kotlin
- 繼承
所有類默認都是繼承自Any的
所有類默認都是不可繼承的(final)
只有明確聲明open或abstract的類才可以被繼承
open class Animal (name: String) {
}
如果子類有主構造函數(shù), 則基類必須在主構造函數(shù)中立即初始化(類似java中的super)
class Person(name: String, age: Int) : Animal(name) {
}
如果子類沒有主構造函數(shù),則基類必須在次級構造函數(shù)中調(diào)用super或者this
class Person : Animal {
// 次級構造函數(shù)
constructor(name: String) : super(name) {
}
// 次級構造函數(shù)
constructor(name: String, age: Int) : this(name) {
}
}
函數(shù)
- 定義
使用fun關鍵字
如果沒有指定返回值,他就會返回Unit
override fun onCreate(savedInstanceState: Bundle?) {
}
- 指定返回值
fun add(x: Int, y: Int): Int {
return x + y
}
如果返回結果可以用一個表達式表示,可以這樣寫
fun add(x: Int, y: Int): Int = x + y
- 可選參數(shù)
fun toast(message: String, length: Int = Toast.LENGTH_SHORT) {
Toast.makeText(this, message, length).show()
}
這樣調(diào)用時,可以選擇傳一個或兩個參數(shù),類似Java的重載
變量和屬性
在Kotlin中,一切都是對象。沒有像Java中那樣的原始基本類型。這個是非常有幫助的,因為我們可以使用一致的方式來處理所有的可用的類型。
當然,像integer,float或者boolean等類型仍然存在,但是它們?nèi)慷紩鳛閷ο蟠嬖诘摹?/p>
- 基本類型與Java的不同之處
1.數(shù)字類型中不會自動轉型
val i:Int=7
val d: Double = i.toDouble()
2.位運算
// Java
int bitwiseOr = FLAG1 | FLAG2;
int bitwiseAnd = FLAG1 & FLAG2;
// Kotlin
val bitwiseOr = FLAG1 or FLAG2
val bitwiseAnd = FLAG1 and FLAG2
3.可以省略變量的類型
val i = 12 // An Int
val iHex = 0x0f // 一個十六進制的Int類型
val l = 3L // A Long
4.一個String可以像數(shù)組那樣訪問,并且被迭代
val s = "Example"
val c = s[2] // 這是一個字符'a'
// 迭代String
val s = "Example"
for(c in s){
print(c)
}
- 變量
變量可以很簡單地定義成可變(var)和不可變(val)的變量。這個與Java中使用的final很相似。但是不可變在Kotlin(和其它很多現(xiàn)代語言)中是一個很重要的概念。
一個不可變對象意味著它在實例化之后就不能再去改變它的狀態(tài)了。如果你需要一個這個對象修改之后的版本,那就會再創(chuàng)建一個新的對象。這個讓編程更加具有健壯性和預估性。在Java中,大部分的對象是可變的,那就意味著任何可以訪問它這個對象的代碼都可以去修改它,從而影響整個程序的其它地方。
不可變對象也可以說是線程安全的。
所以在Kotlin中,如果我們想使用不可變性,我們編碼時思考的方式需要有一些改變。一個重要的概念是:盡可能地使用val。除了個別情況(特別是在Android中,有很多類我們是不會去直接調(diào)用構造函數(shù)的),大多數(shù)時候是可以的。
定義常量與變量
var <標識符> : <類型> = <初始化值>
val <標識符> : <類型> = <初始化值>
val b = 1 // 系統(tǒng)自動推斷變量類型為Int
val c: Int // 如果不在聲明時初始化則必須提供變量類型
c = 1 // 明確賦值
我們通常不需要去指明類的類型,如果我們需要使用更多的范型類型,則需要指定:
val a: Any = 23
val c: Context = activity
- 字符串模板
$ 表示一個變量名或者變量值
$varName 表示變量值
${varName.fun()} 表示變量的方法返回值
var a = 1
// 模板中的簡單名稱:
val s1 = "a is $a"
a = 2
// 模板中的任意表達式:
val s2 = "${s1.replace("is", "was")}, but now is $a"
- NULL檢查機制
//類型后面加?表示可為空
var age: String? = "23"
//拋出空指針異常
val ages = age!!.toInt()
//不做處理返回 null
val ages1 = age?.toInt()
//age為空返回-1
val ages2 = age?.toInt() ?: -1
- 類型檢測及自動類型轉換
fun getStringLength(obj: Any): Int? {
if (obj !is String)
return null
// 在這個分支中, `obj` 的類型會被自動轉換為 `String`
return obj.length
}
- 屬性
在Kotlin中,如果沒有任何指定,屬性會默認使用getter和setter。當然它也可以修改為你自定義的代碼,并且不修改存在的代碼:
public classs Person {
var name: String = ""
get() = field.toUpperCase()
set(value){
field = "Name: $value"
}
}
訪問屬性
//這里對屬性的訪問,并不是像Java里面一樣,直接訪問屬性的本身,而是默認調(diào)用了getter 和 setter 方法。
val person = Person()
val name = person.name
類中聲明的屬性,一定要初始化,否則會編譯錯誤。除非你對屬性使用了abstract或者lateinit進行修飾
var name: String = ""
abstract var size : Int