1.接口
interface Movable {var maxSpeed: Intvar wheels: Intfun move(movable: Movable): String}class Car(var name: String, override var wheels: Int = 4, _maxSpeed: Int) : Movable {override var maxSpeed: Int = _maxSpeedget() = fieldset(value) {field = value}override fun move(movable: Movable): String {TODO("Not yet implemented")}}fun main() {val car = Car("1",4,8)println(car.maxSpeed)
}
1.1 接口屬性默認實現
interface Movable {val maxSpeed: Intget() = (1..500).shuffled().first()//相當于給這個屬性賦值 每次不一樣但他不是修改它 只是修改了它的get方法 所有只讀變量不可賦值var wheels: Intfun move(movable: Movable): String}class Car(var name: String, override var wheels: Int = 4) : Movable {override val maxSpeed: Intget() = super.maxSpeedoverride fun move(movable: Movable): String {TODO("Not yet implemented")}}fun main() {val car = Car("1",4)println(car.maxSpeed)println(car.maxSpeed)println(car.maxSpeed)println(car.maxSpeed)
}
?2.抽象類
abstract class Gun(val range:Int){abstract fun pullTrigger():String
}abstract class Gun1(val a:Int){abstract fun pullTrigger():String
}
class AK47(val price:Int):Gun(range = 80),Movable{override fun pullTrigger(): String {return "AK47 shooting"}override var wheels: Intget() = TODO("Not yet implemented")set(value) {}}
3.泛型
class MagicBox<T> (item:T){var subject:T = item}class Boy(val name:String,val age:Int)class Dog(val weight:Int)fun main() {val magicBox1 = MagicBox(Boy("Jack", 20))val magicBox2 = MagicBox(Dog( 20))println(magicBox1.subject is Boy)println(magicBox2.subject is Dog)}
4.泛型函數
class MagicBox<T> (item:T){var subject:T = itemvar available = falsefun fetch():T?{return subject.takeIf { available } //true返回 this false返回null}}class Boy(val name:String,val age:Int)class Dog(val weight:Int)fun main() {val magicBox1 = MagicBox(Boy("Jack", 20))val magicBox2 = MagicBox(Dog( 20))magicBox1.available =trueprintln(magicBox1.fetch())magicBox2.available=trueprintln(magicBox2.fetch())magicBox2.fetch()?.run {println("you find $weight")}
}
?5.多泛型參數
class MagicBox<T>(item: T) {var subject: T = itemvar available = falsefun fetch(): T? {return subject.takeIf { available } //true返回 this false返回null}//return -> Rfun <R> fetch(subjectModFunction: (T) -> R): R? {return subjectModFunction(subject).takeIf { available }}
}class Boy(val name: String, val age: Int)class Dog(val weight: Int)fun main() {val magicBox1 = MagicBox(Boy("Jack", 20))magicBox1.available =trueval fetch = magicBox1.fetch {Boy("男人", 30)}println(fetch)println(fetch?.name)println(fetch?.age)
}
6.泛型類型的約束
7. vararg關鍵字與get函數
vararg相當于Java的可變參數??Int ... age 類似效果
class MagicBox<T:Human>( vararg item: T) {var subject: Array<out T> = itemvar available = falsefun fetch(index:Int): T? {return subject[index].takeIf { available } //true返回 this false返回null}//return -> Rfun <R> fetch(index: Int,subjectModFunction: (T) -> R): R? {return subjectModFunction(subject[index]).takeIf { available }}
}
open class Human(val age:Int)class Boy(val name: String, age: Int):Human(age)class Dog(val weight: Int)fun main() {val magicBox1 = MagicBox(Boy("Jack0", 20),Boy("Jack1", 20),Boy("Jack2", 20),Boy("Jack3", 20))magicBox1.available =trueval fetch = magicBox1.fetch(3) {it}println(fetch)println(fetch?.name)println(fetch?.age)
}
8.get函數
也就是運算符重載
class MagicBox<T:Human>( vararg item: T) {var subject: Array<out T> = itemvar available = falsefun fetch(index:Int): T? {return subject[index].takeIf { available } //true返回 this false返回null}//return -> Rfun <R> fetch(index: Int,subjectModFunction: (T) -> R): R? {return subjectModFunction(subject[index]).takeIf { available }}operator fun get(index: Int):T?{return subject[index]}}
open class Human(val age:Int)class Boy(val name: String, age: Int):Human(age)class Dog(val weight: Int)fun main() {val magicBox1 = MagicBox(Boy("Jack0", 20),Boy("Jack1", 20),Boy("Jack2", 20),Boy("Jack3", 20))magicBox1.available =trueval fetch = magicBox1.fetch(3) {it}println(fetch)println(fetch?.name)println(fetch?.age)println(magicBox1[3]?.name)
}
9. out 協變 in 逆變 invariant(不變)
?
//out
interface Production<out T> {fun product(): T
}//in
interface Consumer<in T> {fun consume(item: T)
}//不變
interface ProductionConsumer<T> {fun product(): Tfun consume(item: T)
}open class Foodopen class FastFood : Food()class Burger : FastFood()//漢堡生產者
//食品商店
class FoodStore : Production<Food> {override fun product(): Food {println("Product Food")return Food()}}class FastFoodStore : Production<FastFood> {override fun product(): FastFood {println("Product FastFood")return FastFood()}}class BurgerStore : Production<Burger> {override fun product(): Burger {println("Product Burger")return Burger()}}//消費者
class EveryBody : Consumer<Food> {override fun consume(item: Food) {println("consume food")}}class ModernPeople : Consumer<FastFood> {override fun consume(item: FastFood) {println(item is Burger)println("consume FastFood")}}class AmericanPeople : Consumer<Burger> {override fun consume(item: Burger) {println("consume Burger")}}fun main() {//賦值val production1: Production<Food> = FoodStore()val product = production1.product()//用了Out關鍵字 子類轉父類泛型 泛型可以協變和逆變val production2: Production<Food> = FastFoodStore()val production3: Production<Food> = BurgerStore()//in 父類轉子類泛型val consumer1: Consumer<Burger> = EveryBody()val consumer2: Consumer<Burger> = ModernPeople()consumer2.consume(Burger())val consumer3: Consumer<Burger> = AmericanPeople()}
10. reified關鍵字
?reified 和 inline 關鍵字配合使用能夠實現泛型類型判斷。因為匿名函數會被優化到這個隨機類型函數中,那么就能夠知道具體類型是啥了
這個函數的返回類型由backup函數的返回類型決定 和類定義的泛型無關 也就是類的泛型沒有起到任何約束作用 ?你寫一個String都可以
class MagicBox<T : Human>() {//產生一個指定類型的對象,如果不是指定類型的對象,就通過backup函數生成一個指定類型的對象
// fun <T> randomOrBackUp(backup: () -> T): T {
// val items:List<out Human> = listOf(
// Boy("Jack", 20),
// Man("John", 35)
// )
// val random:Human =items.shuffled().first()
// return if (random is T){ //T會被擦除
// random
// }else{
// backup()
// }
//
// }inline fun <reified T> randomOrBackUp(backup: () -> T): T { //內聯函數它就會被替換,泛型擦除從而解決 類型將會保留下來val items:List<Human> = listOf(Boy("Jack", 20),Man("John", 35))val random:Human =items.shuffled().first()return if (random is T){ //T會被擦除random}else{backup()}}}open class Human(val age: Int)class Boy(val name: String, age: Int) : Human(age){}class Man(val name: String, age: Int) : Human(age){override fun toString(): String {return "Man(name='$name' age ='$age')"}
}fun main() {val box1:MagicBox<Boy> = MagicBox()val subject:Man = box1.randomOrBackUp {Man("Jimmy", 36)}println(subject)
}
11.定義擴展函數
//給字符串追加若干個感嘆號
fun String.addExt(amount:Int =1 ):String{return this + "!".repeat(amount)
}fun main() {println("abc".addExt(3))
}
//給字符串追加若干個感嘆號
fun String.addExt(amount:Int =1 ):String{return this + "!".repeat(amount)
}fun Any.easyPring(){println(this)
}
fun Any.easyPring1(){println(this.toString()+1)
}fun main() {println("abc".addExt(3))"abc".easyPring()
}
可以用private修飾符,只能在此文件下使用
12.泛型擴展函數
//給字符串追加若干個感嘆號
fun String.addExt(amount:Int =1 ):String{return this + "!".repeat(amount)
}private fun <T> T.easyPring():T{println(this)return this;
}
fun Any.easyPring1(){println(this.toString()+1)
}fun main() {println("abc".addExt(3))"abc".easyPring().addExt(3).easyPring()
}
?13.擴展屬性
val String.numVowelsget() = count{ "aeiou".contains(it) }//true 計數器加1 fun <T> T.easyPrint():T{println(this)return this
}fun main() {"The people's Republic of China".numVowels.easyPrint()val count = "the".count()println(count)}
?14. 可空類型擴展函數
fun String?.printWithDefault (default:String) = print(this ?: default)//如果為null就為defaultfun main() {val nullableString :String? = "asdas";nullableString.printWithDefault("jmj")
}
15. infix關鍵字
infix fun String?.printWithDefault (default:String) = print(this ?: default)//infix 對一個參數的函數 可以簡化寫法,去掉調用的點和括號fun main() {val nullableString :String? = "asdas";nullableString printWithDefault "jmj"
}
?16.定義擴展文件
package com.jason.kotlin.extensionfun <T> Iterable<T>.randomTask():T = this.shuffled().first()
import com.jason.kotlin.extension.randomTaskfun main() {val randomTask = listOf<String>("jmj", "sada", "asd").randomTask()println(randomTask)
}