热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android—Kotiln基础教程(五)

前言在上一篇中主要讲解了Kotlin关于集合相关的知识点,在本篇中,将会对Kotlin的对象进行详解!1.对象1.1示例一(无构造函

前言

在上一篇中主要讲解了Kotlin关于集合相关的知识点,在本篇中,将会对Kotlin的对象进行详解!


1. 对象


1.1 示例一(无构造函数)

class Player {//分析点1var name = "abc"get() = field.capitalize()set(value) {field = value.trim()}var age = 10 get() = field.absoluteValueprivate set(value) { field = value.absoluteValue}val rolledValue//取随机数get() = (1 until 6).shuffled().first()var words: String? = null //分析点2fun saySomeThine() { //分析点3words?.also { "Hello ${it.toUpperCase()}" }.run(::println)}
}
fun main{var player = Player()player.name = "tom"//player.age=-10 //因为set被改成私有,所以这里报错player.words="main hello" println(player.name)println(player.age)println(player.rolledValue)player.saySomeThine()
}

定义了一个对象,里面有对应的成员属性。注意看这里面的分析点:


  • 分析点1:分别实现了对应的get、set方法,并且在对应的方法里实现了对应的逻辑。
  • 分析点2:该成员变量并没有任何get、set方法
  • 分析点3:在方法saySomeThine里,对成员属性使用了.also关键字,最后再打印

运行效果:

Tom
10
4
main hello

从这个运行效果可以看到:对象里的成员,就算不实现对应的get、set方法,并且在没有使用private情况下,在外部依旧可以调用对应的get、set方法


1.2 示例二(有主构造函数)

// ----------------初始化
class Player1(_name: String,_age: Int,_isNormal: Boolean) {var name = _nameget() = field.toLowerCase()private set(value) {field = value.trim()}private var age = _agevar isNormal = _isNormalfun playerInfo() {//println(_name) //会报错println("name: $name; age:$age ;isNormal $isNormal")}
}fun main() {var player = Player1("Tom", 20, true)player.playerInfo()}

运行效果

name: tom; age:20 ;isNormal true

从这段代码看,这个Player1应该是一个拥有有参构造方法的对象。而对应的_name、_age、_isNormal,就是对应构造方法里的构造参数,有效期也仅在对应的构造方法里。


1.3 示例三(有主次构造函数)

class Player2(_name: String,var age: Int = 12, //执行顺序 1var isNormal: Boolean) {var name = _name //执行顺序2get() = field.capitalize()private set(value) {field = value.trim()}fun playerInfo() {println("name: $name; age:$age ;isNormal $isNormal")}//次构造函数【】 这里的this()相当于执行了主构造函数 相当于顺序1和2constructor(name: String) : this(name, age = 100, isNormal = false ) {this.name = name.toUpperCase()println("constructor----------")//执行顺序 4}init { // 执行顺序3//初始化代码块 会在构造类实例时执行// 则可以 在这进行 数值的检查 满足条件则抛出异常println("init----------")require(age > 10) { println("age must be positive") }require(name.isNotBlank()) { println("player must have a name") }}
}fun main() {var player2=Player2("Tom", 20, true)player2.playerInfo()var player3 = Player2("bob", isNormal = false)player3.playerInfo()var player4=Player2("hqk")player4.playerInfo()
}

运行效果:

init----------
name: Tom; age:15 ;isNormal true
init----------
name: Bob; age:12 ;isNormal false
init----------
constructor----------
name: HQK; age:100 ;isNormal false

这次在代码里面加入了constructor以及init,constructor的意思就是创建一个次构造函数;而init相当于java里面的static代码块。里面对应的执行顺序在注释里标注清楚了。

init代码块里含有require方法,这里面的意思就是:当里面的表达式不成立/false时,将直接报错,自定义错误信息就在后面闭包里实现。


1.4 示例四(延迟初始化)

class Player3 {lateinit var equipment: Stringfun ready() {equipment = "sharp knife"}fun battle() {if (::equipment.isInitialized) println(equipment)}
}fun main{var palyer3 = Player3()palyer3.ready() //必须 调用该方法 才能使用对应的属性变量palyer3.battle()
}

运行效果:

sharp knife

在之前的学习中,我们认知到,当我们定义变量的时候,要么一开始赋初始值,要么通过.?表明这个变量为可空。但在对象的使用里,我既不想一开始赋初始值,也不想让这个变量为可空的,那就只有通过lateinit表明这个属性变量需要在后面初始化(使用它之前)!

那万一在使用它之前未初始化该怎么办呢?岂不是就直接报空指针异常了?Kotlin也提供了对应的解决方案:只要无法确认 lateinit 变量是否完成初始化,可以执行 isInitialized 检查


1.5 示例五(惰性初始化)


class Player4(_name: String) {var name = _nameval config by lazy { loadConfig() }private fun loadConfig(): Boolean {println("loading...")return false}
}fun main{var play4 = Player4("Tom");println(play4.config)
}

运行效果

loading...
false

这里我们看到,当定义成员属性时,使用了by lazy {}的方式,让config实现了惰性初始化。当使用play4.config成员属性时,它才会初始化相应的操作。


1.6 示例六(初始化陷阱)

class Player5() {init {//这样会直接报错blood = this.blood.times(4)}var blood = 100
}

当我们将变量放在init闭包后时,将会发现代码居然报了语法错误。解决方案也很简单,只需要将init闭包放在最后即可。

class Player6() {var blood = 100init {//这样就不会报错blood = this.blood.times(4)}
}fun main{var play6=Player6()println(play6.blood )
}

运行效果:

400

1.7 示例七(对象的继承)

class Player7() {val name: Stringprivate fun firstLetter() = name[0]init {name = "Jack" //分析点1firstLetter()}//--------------继承----------------open class Product(val name: String) { //分析点2open fun description() = "Product: $name"open fun load() = "Nothing..."fun add(num1: Int, num2: Int) = num1 + num2 //该方法不可被子类重写}class LuxuryProduct : Product("Java") {//---重载override fun load() = "Java " + description()}
}
/*** 类型转换*/
fun sale(p: Player7.Product) {println(p.load())
}fun main() {val play7 = Player7()println(play7.name)val product = LuxuryProduct()product.description().run(::println)product.load().run(::println)//类型检测println(product is LuxuryProduct)println(product is Player7.Product)sale(product)sale(product as Player7.Product) //分析点3
}

我们先看这几点分析点:


  • 分析点1:和上面示例一样,当init代码块在对应的属性定义下方时,可在这闭包里初始化对应变量,即使变量是用val修饰的,依然能够初始化。
  • 分析点2:当我们想是用继承时,可以通过open class XXX定义被继承的对象,里面的方法如果想要被子对象重写的话可使用open修饰对应的方法。子类继承父类语法为:class 子类 : 父类
  • 分析点3:当我们想进行对象的转换时,可使用as关键字强转对应的对象。

运行效果

Jack
Product: Java
Java Product: Java
true
true
Java Product: Java
Java Product: Java

结束语

好了,本篇到这里就结束了,本想着在这篇吧对象讲完的,奈何发现内容太丰富了。还有很多很多,加上时间不允许了,还要写那个代码撸猫,所以暂时放到下一篇了。


推荐阅读
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
author-avatar
零摄氏度玫瑰_460
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有