1.接口

Kotlin
interface Movable {
var maxSpeed: Int
var wheels: Int
fun move(movable: Movable): String
}
class Car(var name: String, override var wheels: Int = 4, _maxSpeed: Int) : Movable {
override var maxSpeed: Int = _maxSpeed
get() = field
set(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 接口属性默认实现

Kotlin
interface Movable {
val maxSpeed: Int
get() = (1..500).shuffled().first()//相当于给这个属性赋值 每次不一样但他不是修改它 只是修改了它的get方法 所有只读变量不可赋值
var wheels: Int
fun move(movable: Movable): String
}
class Car(var name: String, override var wheels: Int = 4) : Movable {
override val maxSpeed: Int
get() = super.maxSpeed
override 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.抽象类

Kotlin
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: Int
get() = TODO("Not yet implemented")
set(value) {}
}
3.泛型

Kotlin
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.泛型函数

Kotlin
class MagicBox<T> (item:T){
var subject:T = item
var available = false
fun 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 =true
println(magicBox1.fetch())
magicBox2.available=true
println(magicBox2.fetch())
magicBox2.fetch()?.run {
println("you find $weight")
}
}
5.多泛型参数

Kotlin
class MagicBox<T>(item: T) {
var subject: T = item
var available = false
fun fetch(): T? {
return subject.takeIf { available } //true返回 this false返回null
}
//return -> R
fun <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 =true
val fetch = magicBox1.fetch {
Boy("男人", 30)
}
println(fetch)
println(fetch?.name)
println(fetch?.age)
}
6.泛型类型的约束

7. vararg关键字与get函数
vararg相当于Java的可变参数 Int ... age 类似效果

Kotlin
class MagicBox<T:Human>( vararg item: T) {
var subject: Array<out T> = item
var available = false
fun fetch(index:Int): T? {
return subject[index].takeIf { available } //true返回 this false返回null
}
//return -> R
fun <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 =true
val fetch = magicBox1.fetch(3) {
it
}
println(fetch)
println(fetch?.name)
println(fetch?.age)
}
8.get函数
也就是运算符重载
Kotlin
class MagicBox<T:Human>( vararg item: T) {
var subject: Array<out T> = item
var available = false
fun fetch(index:Int): T? {
return subject[index].takeIf { available } //true返回 this false返回null
}
//return -> R
fun <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 =true
val fetch = magicBox1.fetch(3) {
it
}
println(fetch)
println(fetch?.name)
println(fetch?.age)
println(magicBox1[3]?.name)
}
9. out 协变 in 逆变 invariant(不变)


Kotlin
//out
interface Production<out T> {
fun product(): T
}
//in
interface Consumer<in T> {
fun consume(item: T)
}
//不变
interface ProductionConsumer<T> {
fun product(): T
fun consume(item: T)
}
open class Food
open 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都可以
Kotlin
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.定义扩展函数

Kotlin
//给字符串追加若干个感叹号
fun String.addExt(amount:Int =1 ):String{
return this + "!".repeat(amount)
}
fun main() {
println("abc".addExt(3))
}
Kotlin
//给字符串追加若干个感叹号
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.泛型扩展函数

Kotlin
//给字符串追加若干个感叹号
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.扩展属性
Kotlin
val String.numVowels
get() = 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. 可空类型扩展函数
Kotlin
fun String?.printWithDefault (default:String) = print(this ?: default)//如果为null就为default
fun main() {
val nullableString :String? = "asdas";
nullableString.printWithDefault("jmj")
}
15. infix关键字

Kotlin
infix fun String?.printWithDefault (default:String) = print(this ?: default)//infix 对一个参数的函数 可以简化写法,去掉调用的点和括号
fun main() {
val nullableString :String? = "asdas";
nullableString printWithDefault "jmj"
}
16.定义扩展文件

Kotlin
package com.jason.kotlin.extension
fun <T> Iterable<T>.randomTask():T = this.shuffled().first()
Kotlin
import com.jason.kotlin.extension.randomTask
fun main() {
val randomTask = listOf<String>("jmj", "sada", "asd").randomTask()
println(randomTask)
}
