Kotlin內置數據類型
名稱 | 釋義 |
---|---|
String | 字符串 |
char | 字符 |
Boolean | 布爾型 |
Int | 整型 |
Float | 單精度浮點型 |
Double | 雙精度浮點型 |
List | 集合 |
Set | 無重復元素集合 |
Map | 鍵值對集合 |
變量
可讀可寫變量
var name: String = "Kotlin"
name = "C++"
println(name)
可讀變量
val name: String = "Kotlin"
//下列變量不可修改,因為聲明成val,只能進行讀操作,不能進行寫操作
//name = "C++"
println(name)
自動類型推導機制
根據定義變量時進行初始化,系統(tǒng)可以根據初始化值自動進行類型推導,進而可以省略類型聲明
val name = "Kotlin" //String
val age = 5 //Int
val sex = m' //char
val score = 99.99 //Doble
when表達式
val week = 5
val info = when(week){
1-> "星期一"
2-> "星期二"
3-> "星期三"
4-> "星期四"
5-> "星期五"
6-> "星期六"
7-> "星期天"
else-> "錯誤類型"
}
println(info)
range表達式
val score = 70
when (score) {
in 0..59 -> {
println("不及格")
}
in 60 ..79 -> {
println("及格")
}
in 80 .. 89 -> {
println("良好")
}
else -> {
println("優(yōu)秀")
}
}
字符串模版
val name = "Kotlin"
val age = 7
val score = 32
val detail = "I am $name and $age,I got ${score+10} in the last test."
println(detail)
函數
函數定義
- 在Kotlin中函數默認訪問類型為Public,此處我聲明為private
-
fun
為聲明函數關鍵字 -
add
為函數名 -
a:Int,b:Int
為函數形參 - 形參列表后面有一個
:Int
,代表函數返回Int
private fun add(a:Int,b:Int):Int{
val result = a+b
println(result)
return result
}
函數簡寫
當函數體只有一行代碼時,可以不寫括號,直接在等號后面接代碼即可
private fun add(a:Int,b:Int) = println(a+b)
若函數需要返回值,則直接將計算結果接在等號后面返回
private fun add(a:Int,b:Int):Int = a+b
默認參數
fun printfInfo(name:String,age:Int) = println("I am $name and $age")
fun printfInfo(name:String="Li",age:Int) = println("I am $name and $age")
fun printfInfo(name:String="Li",age:Int=20) = println("I am $name and $age")
具名函數參數
具名參數可以任意調整實參的順序
printfInfo(age = 10,name = "Kotlin")
...
fun printfInfo(name:String,age:Int) = println("I am $name and $age")
Unit函數
在JAVA中void為空返回類型,是一個關鍵字
在Kotlin中Unit是一個類類型,為函數默認返回類型
private fun exe():Unit{
return println()
}
反引號函數
打印分數(20.22)
...
private fun `打印分數`(score:Double){
println("分數=$score")
}
匿名函數
val len = "Kotlin".count()
println("len=$len")
val len1 = "Kotlin,in".count { it->
it == 'i'
}
println("len1=$len1")
隱式返回
函數聲明
val printfScore:(score:Double)->String
函數實現(xiàn),匿名函數無需使用return
返回結果,以最后一行作為返回值進行返回
printfScore = { it->
println("score$it")
"打印成功!"
}
函數調用
printfScore(50.50)
函數作為形參
const val NAME = "Kotlin"
const val AGE = 10
//...
JudgeInfo("Kotlin",10){ info,code->
println("info=$info,code=$code")
}
//...
fun JudgeInfo(name:String,age:Int,respond:(String,Int)->Unit){
val result = name == NAME && age == AGE
if (result == true){
respond("success",200)
}else{
respond("failed",404)
}
}
函數引用
const val NAME = "Kotlin"
const val AGE = 10
//...
JudgeInfo("Kotlin",10,::printfInfo)
fun printfInfo(info:String,code:Int) = println("info=$info,code=$code")
//...
fun JudgeInfo(name:String,age:Int,respond:(String,Int)->Unit){
val result = name == NAME && age == AGE
if (result == true){
respond("success",200)
}else{
respond("failed",404)
}
}
函數作為返回值
const val NAME = "Kotlin"
const val AGE = 10
//...
val exe = JudgeInfo()
println(exe("Kotlin",10))
//...
fun JudgeInfo():(name:String,age:Int)->Boolean{
return { name,age->
val result = name ==NAME && age ==AGE
result
}
}
可空性
在Kotlin中不能直接給一個變量賦值null
,這也極大減少了空異常頻發(fā)問題
如果需要給一個變量賦null,則需要在聲明時,在變量類型后面加一個?
,示意準許此變量在程序中為null
val name:String ? = null
println(name)//打印出null
將一個可空類型字符串變量轉為大寫,需要在調用uppercase
函數時前面加一個?
,代表如果name不為空則執(zhí)行uppercase
函數,否則不執(zhí)行?
后面的函數
var name:String ? = null
name = "kotlin"
val msg = name?.uppercase()
println(msg)
高級函數 let
var name:String ? = null
name = "kotlin"
val msg = name?.let {
it.uppercase()
}
println(msg)
非空斷言
var name:String ? = null
name = "kotlin"
val msg = name!!.uppercase()
println(msg)
空合并操作符
var name:String ? = null
println(name ?: "name為空!")
高級函數
apply函數
- apply函數始終返回對象本身
- apply匿名函數在內部持有當前對象
this
val languages = arrayOf("C++","JAVA","Kotlin","C")
//apply函數始終返回對象本身,且apply匿名函數在內部持有當前對象this
languages.apply {
println("數組長度=${size}")
}.apply {
forEach {
println(it)
}
}.apply {
println("遍歷數組完畢")
}
run函數
- 以最后一行作為返回值返回
- 匿名函數內部持有當前對象
this
val len = languages.run {
filter {
it.contains('C')
}.size
}
println("包含字符C的元素個數=${len}")
with函數
- 以最后一行作為返回值返回
- 匿名函數內部持有當前對象
this
- 不能以拓展函數形式調用,只能將當前對象以形參形式傳遞
val languages = arrayOf("C++","JAVA","Kotlin","C")
val len = with(languages){
filter {
it.contains('C')
}.size
}
println("包含字符C的元素個數=${len}")
also函數
- also函數始終返回對象本身
- 匿名函數內部持有
it
val languages = arrayOf("C++","JAVA","Kotlin","C")
languages.also {
println(it.first())
}.also {
println(it.last())
}.also {
println("元素個數=${it.size}")
}
takeIf函數
如果takeIf
函數內部為true
則返回對象本身,否則返回null
const val NAME = "Kotlin"
const val AGE = 10
fun main() {
val result = JudgeInfo("Kotlin",10)
println(result)
}
fun JudgeInfo(name:String,age:Int):String{
return name.takeIf { name`NAME&&AGE`age } ?: "信息不匹配!"
}
takeUnless函數
takeUnless函數與takeIf函數功能相反,如果takeUnless
內部為true則返回null,否則返回對象本身
集合
List
val languages:List<String> = listOf<String>("C++","C","JAVA","Kotlin","Dart")
// public operator fun get(index: Int): E
//與C++的運算符重載類似
println("第一個元素:${languages[0]}")
languages.forEach {
println(it)
}
列表越界處理
//方法一
val result = languages.getOrElse(5){
"數組越界"
}
println(result)
//方法二
val result1 = languages.getOrNull(1000) ?: "數組越界"
println(result1)
可變List
val languages = mutableListOf("C++","C","JAVA","Kotlin","Dart")
- 刪除List中包含字符C的元素
languages.removeIf {
it.contains('C')
}
languages.forEach{
println(it)
}
- 添加元素
通過運算符重載函數為List添加新元素
public inline operator fun MutableCollection.plusAssign(element: T) {
this.add(element)
}
languages += "C#"
languages += "Basic"
languages.forEach{
println(it)
}
- 遍歷List
forEach
languages.forEach{
println(it)
}
for-in
for(element in languages){
println(element)
}
forEachIndexed
languages.forEachIndexed { index, s ->
println("第${index+1}元素=$s")
}
Set
不允許存在重復元素,如果存在重復元素,會自動忽略
下列輸出C++ C JAVA Kotlin Dart
val languages:Set<String> = setOf<String>("C++","C","JAVA","Kotlin","Dart","C++")
languages.forEach {
print("$it ")
}
println()
元素讀取
languages.elementAt(0)
防止下標越界而導致程序崩潰
//法一
val result1 = languages.elementAtOrNull(1000) ?: "越界"
//法二
val result2 = languages.elementAtOrElse(1000){
"越界"
}
可變Set
val languages:MutableSet<String> = mutableSetOf<String("C++","C","JAVA","Kotlin","Dart","C++")
languages += "Basic"
languages -= "C++"
languages.forEach {
print("$it ")
}
數組
數組定義
val languages = arrayOf<String>("C++","C","JAVA","Kotlin","Dart","C++") //對象數組
val intNumbers = intArrayOf(1,2,3,4,5)
val doubleNumbers = doubleArrayOf(10.1,11.2,12.1)
val charArray = charArrayOf('a','b','c')
讀取數組元素
println(languages[0])
val result1 = languages.elementAtOrElse(1000){
"越界"
}
val result2 =languages.elementAtOrNull(1000) ?: "越界"
println(result1)
println(result2)
Map
map定義
//法一
val map:Map<String,Int> = mapOf("C" to 1,"C++" to 2,"Kotlin" to 3)
//法二
val map1:Map<String,Int> = mapOf(Pair("C",1),Pair("C++",2),Pair("Kotlin",3))
讀取map元素,如果讀取map中沒有的元素,則返回null
val value = map["C"]
println(value)
定義默認值
val value = map.getOrDefault("Go",-1)
println(value)
通過匿名函數定義錯誤讀取
val value = map.getOrElse("Go"){
"沒有對應的值"
}
println(value)
遍歷map
- 法一
val map:Map<String,Int> = mapOf("C" to 1,"C++" to 2,"Kotlin" to 3)
map.forEach { (_, value) ->
print("$value ")
}
- 法二
val map:Map<String,Int> = mapOf("C" to 1,"C++" to 2,"Kotlin" to 3)
map.forEach {
print("${it.value} ")
}
- 法三
val map:Map<String,Int> = mapOf("C" to 1,"C++" to 2,"Kotlin" to 3)
for (entry in map) {
print("${entry.value} ")
}
可變Map
val map:MutableMap<String,Int> = mutableMapOf("C" to 1,"C++" to 2,"Kotlin" to 3)
map += Pair("JAVA",4)
map += "Basic" to 5
map -= "C"
map.forEach { (_, value) ->
print("$value ")
}
類
在Kotlin中,類的成員屬性默認訪問權限為public
class Student{
var name:String = "Kotlin"
//下列get和set默認存在
get() = field
set(value) {
field = value
}
var sex:Char = 'm'
get() = field.uppercaseChar()
set(value) {
field =value.lowercaseChar()
}
private var age:Int = 0
}
fun main() {
val zhangsan = Student()
println(zhangsan.name)
}
主構造函數
//主構造函數,下列形參為輸入類型,不能直接使用,需要通過接收成為變量才能使用
class Student(name: String, age:Int){
fun print(){
//此處不能直接調用name
// println(name)
}
}
通過下列兩種方式,主構造函數的形參就可以在類中使用
//法一
class Student(var name: String, var age:Int){
fun print(){
println(name)
}
}
//法二
class Student(name: String, age:Int){
var name = name
var age = age
fun print(){
println(name)
}
}
次構造函數
次構造函數必須調用主構造函數
class Student(name: String){
var name:String = name
var age:Int = 0
var score:Double = 0.0
//次構造函數必須調用主構造函數
constructor(name: String,age:Int):this(name){
this.name = name
this.age = age
}
constructor(name: String,age:Int,score:Double):this(name){
this.name = name
this.age = age
this.score = score
}
}
fun main() {
val lisi = Student("李四")
val zhangsan = Student("張三",20)
val wangwu = Student("王五",20,50.50)
println(zhangsan.score)
}
lateinit 延遲初始化
class Student{
lateinit var name:String
fun initName(name:String){
this.name = name
}
fun showName(){
val flag = ::name.isInitialized//判斷是否初始化
if(flag){
println(name)
}else{
println("未初始化name")
}
}
}
fun main() {
println(Student().showName())
}
lazy 惰性初始化
class Student{
//當調用的時候才初始化
val name:String by lazy { readName() }
private fun readName(): String {
println("loading...")
println("loading...")
println("loading...")
return "FranzLiszt"
}
}
fun main() {
val zhangsan = Student()
Thread.sleep(3000)
println(zhangsan.name)
}
繼承和重載
在Kotlin中,類默認是final修飾,不能被繼承;只有通過open修飾才能被繼承
//類默認是final修飾,不能被繼承;只有通過open修飾才能被繼承
open class Person(val name:String){
private fun printfName() = println("parent class name:$name")
open fun showName() = println(printfName())
}
class Student(val subname:String): Person(subname){
private fun printfName() = println("sub class name:$name")
override fun showName() = printfName()
}
fun main() {
val person:Person = Student("張三")
person.showName()
}
companion objec 伴生對象
伴生對象,與Java的Static類似,同樣無論調用多少次,伴生對象只會初始化一次
class Student(){
//伴生對象,與Java的Static類似
companion object{
private val name = "student"
fun showName() = println(name)
}
}
fun main() {
println(Student.showName())
}
內部類
內部的類不能訪問外部類屬性,通過添加inner修飾,成為內部類才能訪問
class Person(name:String){
val name = name
//內部的類不能訪問外部類屬性,通過添加inner修飾,成為內部類才能訪問
inner class Male{
fun show() = println("male $name")
}
inner class Female{
fun show() = println("female $name")
}
}
fun main() {
val p = Person("zs")
p.Male().show()
}
嵌套類
嵌套類的內部的類不能訪問外部類屬性
class Person(name:String){
val name = name
class Male{
//不能訪問外部類屬性
//fun show() = println("male $name")
}
class Female{
fun show() = println("嵌套類")
}
}
fun main() {
Person.Female().show()
}
數據類
定義數據類
data class Student(var name:Student,var age:Int)
反編譯上面的數據類,可以看見除了成員變量的get()、set()函數外,還拓展了拷貝函數、toString()、equals()函數等;比起JAVA的JavaBean更加豐富;其中上述擴展的函數只會覆蓋主構造函數的成員屬性,不會覆蓋次構造函數的成員屬性
public final class Student {
@NotNull
private Student name;
private int age;
@NotNull
public final Student getName() {
return this.name;
}
public final void setName(@NotNull Student var1) {
Intrinsics.checkNotNullParameter(var1, "<set-?>");
this.name = var1;
}
public final int getAge() {
return this.age;
}
public final void setAge(int var1) {
this.age = var1;
}
public Student(@NotNull Student name, int age) {
Intrinsics.checkNotNullParameter(name, "name");
super();
this.name = name;
this.age = age;
}
@NotNull
public final Student component1() {
return this.name;
}
public final int component2() {
return this.age;
}
@NotNull
public final Student copy(@NotNull Student name, int age) {
Intrinsics.checkNotNullParameter(name, "name");
return new Student(name, age);
}
// $FF: synthetic method
public static Student copy$default(Student var0, Student var1, int var2, int var3, Object var4) {
if ((var3 & 1) != 0) {
var1 = var0.name;
}
if ((var3 & 2) != 0) {
var2 = var0.age;
}
return var0.copy(var1, var2);
}
@NotNull
public String toString() {
return "Student(name=" + this.name + ", age=" + this.age + ")";
}
public int hashCode() {
Student var10000 = this.name;
return (var10000 != null ? var10000.hashCode() : 0) * 31 + Integer.hashCode(this.age);
}
public boolean equals(@Nullable Object var1) {
if (this != var1) {
if (var1 instanceof Student) {
Student var2 = (Student)var1;
if (Intrinsics.areEqual(this.name, var2.name) && this.age ` var2.age) {
return true;
}
}
return false;
} else {
return true;
}
}
}
運算符重載
下列列出一些常用的重載運算符
表達式 | 翻譯為 |
---|---|
a + b | a.plus(b) |
a - b | a.minus(b) |
a * b | a.times(b) |
a / b | a.div(b) |
a % b | a.rem(b) |
a[i] | a.get(i) |
a += b | a.plusAssign(b) |
a > b | a.compareTo(b) > 0 |
a < b | a.compareTo(b) < 0 |
a++ | a.inc() |
a– | a.dec() |
下面重寫了加減乘除四個運算符,可以與C++的運算符重載做對比,差異如下文章來源:http://www.zghlxwxcb.cn/news/detail-772930.html
- C++直接對運算符進行重新標識,而Kotlin需要進行轉化,例如重載加號運算符,需要改為
plus
函數
class Calculation(private val num1:Int){
//重載加號運算符
operator fun plus(param:Calculation):Calculation = Calculation(num1+param.num1)
//重載減號運算符
operator fun minus(param:Calculation):Calculation = Calculation(num1-param.num1)
//重載乘號號運算符
operator fun times(param:Calculation):Calculation = Calculation(num1*param.num1)
//重載除號運算符
operator fun div(param:Calculation):Calculation{
if (param.num1 ` 0 )return Calculation(0)
return Calculation(num1/param.num1)
}
fun printfNum() = println("num=$num1")
}
fun main(){
val example1 = Calculation(5)
val example2 = Calculation(10)
val result = example1 + example2
result.printfNum()
}
枚舉類
data class WeekInfo(var info:String)
enum class Week(private val weekInfo: WeekInfo) {
Sunday(WeekInfo("星期天")),
Monday(WeekInfo("星期一")),
Tuesday(WeekInfo("星期二")),
Wednesday(WeekInfo("星期三")),
Thursday(WeekInfo("星期四")),
Friday(WeekInfo("星期五")),
Saturday(WeekInfo("星期六"));
fun show() = println("info = ${weekInfo.info}")
fun update(weekInfo: WeekInfo){
this.weekInfo.info = weekInfo.info
println("info = ${weekInfo.info}")
}
}
fun main(){
Week.Friday.show()
Week.Sunday.update(WeekInfo("XINGQITIAN"))
}
代數數據類型
enum class Judge{
Bad,
Mid_Good,
Superior
}
fun testScore(score: Judge): String =
when (score) {
Judge.Bad -> "不及格"
Judge.Mid_Good -> "良好"
Judge.Superior -> "優(yōu)秀"
}
fun main(){
println(testScore(Judge.Superior))
}
密封類
sealed class Scores{
object Fail:Scores()
object Pass:Scores()
object Superior:Scores()
}
fun testScore(score: Scores): String =
when (score) {
is Scores.Fail -> "不及格"
is Scores.Pass -> "良好"
is Scores.Superior -> "優(yōu)秀"
}
fun main(){
println(testScore(Scores.Pass))
}
接口
在Kotlin中,接口實現(xiàn)類不僅要實現(xiàn)其接口的函數,還需要重寫其成員變量文章來源地址http://www.zghlxwxcb.cn/news/detail-772930.html
interface Information{
var name:String
var age:Int
fun showInfo()
}
class Student(stuName:String, stuAge:Int):Information{
override var name: String = stuName
override var age: Int = stuAge
override fun showInfo() {
println("name=$name,age=$age")
}
}
fun main(){
val zhangsan:Student = Student("張三",20)
zhangsan.showInfo()
}
抽象類
abstract class Base{
fun run(){
running(getAnimalName())
eating(getAnimalName())
}
abstract fun getAnimalName():String
abstract fun running(name:String)
abstract fun eating(name:String)
}
class Cat:Base(){
override fun getAnimalName(): String = "Cat"
override fun running(name:String) = println("$name running")
override fun eating(name:String) = println("$name eating")
fun show(){
super.run()
}
}
fun main(){
val cat:Cat = Cat()
cat.show()
}
泛型類
class BasePrintf<T> (private val obj:T){
fun printf() = println("輸出結果:$obj")
}
data class Student(val name:String,val age:Int)
data class Teacher(val name:String,val age:Int,val id:Int)
fun main() {
val zhangsan = Student("張三",20)
val lisi = Teacher("李四",30,111)
BasePrintf(zhangsan).printf()
BasePrintf(lisi).printf()
BasePrintf(111).printf()
BasePrintf("aaa").printf()
}
vararg 動態(tài)參數
class Person<T>(private vararg val params:T){
//out的作用是T只能被讀取,不能修改
private val arrays: Array<out T> = params
fun show(index:Int): T = arrays[index]
fun<o> map(index:Int,action:(T)->o) = action(arrays[index])
}
fun main() {
val param = Person("Kotlin",20,false,99.99)
println(param.show(0))
println(param.show(1))
param.map(3){
println(it)
}
}
協(xié)變&逆變
協(xié)變
- 在泛型前加out,代表此泛型只能被讀取不能被修改
- 泛型的子類對象可以賦值給泛型的父類對象
interface Producer<out T>{
fun produce():T
}
逆變
- 在泛型前加in,代表此泛型只能被修改不能被讀取
- 泛型的具體父類可以賦值給泛型聲明處的子類
interface Consumer<in T>{
fun consumer(param:T)
}
擴展函數
class Student(val name:String,val age:Int)
fun Student.printf() = println("name=$name,age=$age")
fun main() {
val zhangsan = Student("張三",20)
zhangsan.printf()
}
單例模式
餓漢式
object Student
懶漢式
class Student{
companion object{
private var instance:Student ? = null
get() {
if (field ` null) field = Student()
return field
}
fun getInstanceAction():Student = instance!!
}
}
懶漢式-加鎖
class Student{
companion object{
private var instance:Student ? = null
get() {
if (field ` null) field = Student()
return field
}
@Synchronized
fun getInstanceAction():Student = instance!!
}
}
懶漢式-雙重校驗
class Student private constructor(){
companion object{
val instance:Student by lazy (mode = LazyThreadSafetyMode.SYNCHRONIZED){Student()}
}
}
到了這里,關于Kotlin基礎語法的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!