Kotlin学习 6

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)
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/261852.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

typescript 索引签名类型

ts索引类型简介 在TypeScript中&#xff0c;索引签名类型&#xff08;Index Signature Type&#xff09;是一种特殊的类型&#xff0c;它定义了对象中键的类型以及相应的值的类型。通过使用索引签名类型&#xff0c;我们可以表示一个对象&#xff0c;该对象的键可以是任意类型…

pytest 框架自动化测试

随笔记录 目录 1. 安装 2. 安装pytest 相关插件 2.1 准备阶段 2.2 安装 2.3 验证安装成功 3. pytest测试用例的运行方式 3.1 主函数模式 3.1.1 主函数执行指定文件 3.1.2 主函数执行指定模块 3.1.3 主函数执行某个文件中的某个类、方法、函数 3.1.4 主函数执行生…

Vue3之ref与reactive的基本使用

ref可以创建基本类型、对象类型的响应式数据 reactive只可以创建对象类型的响应式数据 接下来让我为大家介绍一下吧&#xff01; 在Vue3中&#xff0c;我们想让数据变成响应式数据&#xff0c;我们需要借助到ref与reactive 先为大家介绍一下ref如何使用还有什么注意点 我们需…

【笔记------STM32】MX_RTC_Init()初始化RTC时RTC_ISR_INITF位超时失败的解决方法

RTC和flash有点像&#xff0c;有些功能需要解锁才能配置&#xff0c;虽然cubeMX生成的RTC部分的解锁配置正确&#xff0c;但却没有配置好前提条件&#xff1a;关闭PWR模块的备份域写保护使能&#xff0c;有点奇怪&#xff0c;手动关掉就好了 现象&#xff1a;进入RTC_EnterInit…

世界顶级名校计算机专业学习使用教材汇总

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-IauYk2cGjEyljid0 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

[嵌入式系统-24]:RT-Thread -11- 内核组件编程接口 - 网络组件 - TCP/UDP Socket编程

目录 一、RT-Thread网络组件 1.1 概述 1.2 RT-Thread支持的网络协议栈 1.3 RT-Thread如何选择不同的网络协议栈 二、Socket编程 2.1 概述 2.2 UDP socket编程 2.3 TCP socket编程 2.4 TCP socket收发数据 一、RT-Thread网络组件 1.1 概述 RT-Thread 是一个开源的嵌入…

SpringCloud(15)之SpringCloud Gateway

一、Spring Cloud Gateway介绍 Spring Cloud Gateway 是Spring Cloud团队的一个全新项目&#xff0c;基于Spring 5.0、SpringBoot2.0、 Project Reactor 等技术开发的网关。旨在为微服务架构提供一种简单有效统一的API路由管理方式。 Spring Cloud Gateway 作为SpringCloud生态…

ThreadLocal的一些理解

阅读本篇博客您将了解如下内容&#xff1a; TreadLocal的作用。ThreadLocal的实现原理。ThreadLocal是否会引起内存泄漏&#xff0c;在什么样的条件下引发&#xff0c;如何避免。 1、ThreadLocal的作用 使用线程封闭的指导思想来解决变量共享的并发安全问题&#xff0c;–可以…

【数据库】达梦数据库DM8开发版安装

目录 一、达梦数据库概述 1.1 达梦数据库简介 1.2 产品特性 1.3 产品架构 二、安装前准备 2.1 新建 dmdba 用户 2.2 修改文件打开最大数 2.3 挂载镜像 2.4 新建安装目录 2.5 修改安装目录权限 三、数据库安装 3.1 命令行安装 3.2 配置环境变量 四、配置实例 4.1…

十六、多边形填充和绘制

项目功能实现&#xff1a;对多边形进行轮廓绘制和填充 按照之前的博文结构来&#xff0c;这里就不在赘述了 一、头文件 mult-drawing.h #pragma once#include<opencv2/opencv.hpp>using namespace cv;class Mult_Drawing { public:void mult_drawing(); };#pragma onc…

Rman全备和增量备份说明

RMAN备份分为全备和增量备份&#xff0c;全备不能成为增量备份策略的一部分&#xff0c;它也不能作为后续增量备份的基础。 RMAN增量备份分为0、1、2三级&#xff0c;其中0级备份是增量备份的基础&#xff0c;备份内容也跟全备份一样&#xff0c;要使用增量备份&#xff0c;必…

Android 面试问题 2024 版(其二)

Android 面试问题 2024 版&#xff08;其二&#xff09; 六、多线程和并发七、性能优化八、测试九、安全十、Material设计和 **UX/UI** 六、多线程和并发 Android 中的进程和线程有什么区别&#xff1f; 答&#xff1a;进程是在自己的内存空间中运行的应用程序的单独实例&…

[计算机网络]---TCP协议

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一 、TCP协…

基于SpringBoot + Layui的社区物业管理系统

项目介绍 社区物业管理系统是基于java编程语言&#xff0c;springboot框架&#xff0c;idea工具&#xff0c;mysql数据库进行开发&#xff0c;本系统分为业主和管理员两个角色&#xff0c;业主可以登陆系统&#xff0c;查看车位费用信息&#xff0c;查看物业费用信息&#xff0…

代码随想录算法训练营第58天 | 392.判断子序列 115.不同的子序列

判断子序列 这道题可以双指针方法解决。 class Solution { public:bool isSubsequence(string s, string t) {int s_index 0;for(int t_index 0; t_index < t.size(); t_index) {if(s[s_index] t[t_index]) {s_index;}}return s_index s.size();} };用动态规划也是可解…

力扣OJ题——随机链表的复制

题目&#xff1a; 138. 随机链表的复制 给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 要求&#xff1a;构造这个链表的 深拷贝 深拷贝应该正好由 n 个 全新 节点组成&#xff0c;其中…

Vue状态管理库-Pinia

一、Pinia是什么&#xff1f; Pinia 是 Vue 的专属状态管理库&#xff0c;它允许支持跨组件或页面共享状态&#xff0c;即共享数据&#xff0c;他的初始设计目的是设计一个支持组合式API的 Vue 状态管理库&#xff08;因为vue3一个很大的改变就是组合式API&#xff09;,当然这…

简介高效的 CV 入门指南: 100 行实现 InceptionResNet 图像分类

简介高效的 CV 入门指南: 100 行实现 InceptionResNet 图像分类 概述InceptionResNetInception 网络基本原理关键特征 ResNet 网络深度学习早期问题残差学习 InceptionResNet 网络InceptionResNet v1InceptionResNet v2改进的 Inception 模块更有效的残差连接设计 100 行实现 I…

Docker本地部署Rss订阅工具并实现公网远程访问

文章目录 1. Docker 安装2. Docker 部署Rsshub3. 本地访问Rsshub4. Linux安装Cpolar5. 配置公网地址6. 远程访问Rsshub7. 固定Cpolar公网地址8. 固定地址访问 Rsshub是一个开源、简单易用、易于扩展的RSS生成器&#xff0c;它可以为各种内容生成RSS订阅源。 Rsshub借助于开源社…

JDBC简介

JDBC体系结构 Java Data Base Connectivity&#xff08;JDBC&#xff09;&#xff0c;Java数据库连接。 JDBC重要的类和接口 JDBC API 定义了一组用于与数据库进行通信的接口和类&#xff0c;这些接口和类都定义在Java.sql包中。 类或接口作用DriverManager处理驱动程序的加…