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

Kotlin入门与进阶:基础知识(二)类、对象、数组、区间

上一篇文章简单介绍了Kotlin的基本数据类型(Kotlin简介与基本数据类型),这一篇主要讲解Kotlin的类与对象,数组与区间,以及智能类型转换。类与对象类是一个抽象的概念,是

上一篇文章简单介绍了Kotlin的基本数据类型(Kotlin简介与基本数据类型),这一篇主要讲解Kotlin的类与对象,数组与区间,以及智能类型转换。

类与对象

是一个抽象的概念,是具有某些特征的事物的概括,并不代指任意具体的事物,而对象是一个具体的概念,与类相对,用来描述某一种类的具体个体。

比如:“人” 是一个类,而 “一个三十五岁,身高一米八,慈眉善目的男工程师”则是这个类的一个对象。

在Kotlin中,类的写法是:

class <类名> {<成员>}

废话不多说,看代码:

open class 人(var 性格:String,var 长相:String,var 身高:String){
init {
println("创造了一个${this.javaClass.simpleName},性格:$性格,长相:$长相,身高:$身高")
}
}
class 美女(性格: String,长相: String,身高:String):人(性格,长相,身高)
class 帅哥(性格: String,长相: String,身高:String):人(性格,长相,身高)
fun main(args: Array) {
val 女仆:美女 = 美女("暴怒","慈祥","一米三")
val 兽人:帅哥 = 帅哥("狂暴","惊悚","三米")
}

open修饰“人”这个类,表示这个类可以被继承,在Kotlin中,所有的类默认都是“final”的,不可以被继承。

一个类通常可以有很多个具体的对象,但一个对象本质上只能从属于一个类。

子类拥有父类一切特征,也可以定义自己的特征

所有的类最终继承自Any

关于“继承”,“父类”和“子类”的概念,与Java基础知识无异,在此不做赘述。

“人”包含三个属性:长相,性格,身高,Kotlin每个类有自带的init()方法,在新建类的时候会自动调用。

子类与父类之间通过 :来继承。

可以看到,新建子类时 , val 女仆:美女 = &#8230;    跟定义基本类型 val mInt:Int = &#8230; 形式上其实是一样的,

在Kotlin中,我们完全可以把类当做一个基本类型,便于理解。

类的创建相比Java也简洁许多,不再需要 “new” 的字段。

判断一个类是否其他类的子类 ,通过 is 来进行。

比如 println(兽人 is  人),输出 true

上面代码段的执行结果:

创造了一个美女,性格:暴怒,长相:慈祥,身高:一米三
创造了一个帅哥,性格:狂暴,长相:惊悚,身高:三米

区间

“区间”,是一个数学上的概念,表示数之间的范围,它与Kotlin之中“区间”的定义,大致相同。

区间(Range)是ClosedRange的子类,编程中最常用的是IntRange。

基本写法:

0..100表示【0,100】

0 until 100 表示【1,100)

param in 0..100 用来判断 param 是否在区间【0,100】中

有些哥们可能就问了:博主,这个【】 和(),啥区别啊?

emm。。。兄弟,高中《代数》了解一下。

《Kotlin入门与进阶:基础知识(二)类、对象、数组、区间》

示例:

val mIntRange:IntRange = 0 until 100
un main(args: Array) {
println( 1 in mIntRange)
}
输出结果 : true

数组

也就是我们常说的 “Array”。

数组的英文定义是: 

An impressive display or range of a particular type of thing or an ordered arrangement ,in partucular.

有看到一个“数”字吗? 所以“数组”跟“数” 实际上并没有什么关系。数组其实是一系列的对象。

《Kotlin入门与进阶:基础知识(二)类、对象、数组、区间》

在Kotlin中,数组的基本写法是(以String为例):

val array:Array[String] = arrayOf(&#8230;)

数组的一些基本操作:

arrayp[i] 第i个成员

array[i] = &#8220;wakaka&#8221; 给第i个成员赋值

array.length 数组长度

跟Java无区别。

在Kotlin中,为了避免无谓的拆箱与装箱,基本数据类型的数组是定制的,

《Kotlin入门与进阶:基础知识(二)类、对象、数组、区间》

看以下示例:

val mCharArray:CharArray = charArrayOf('a','\n','\t','5','*','=')
val mIntArray:IntArray = intArrayOf(2,4,6,8,10)
val mRenArray:Array<人> = arrayOf(美女("谨慎","大众","一米六"),帅哥("霸道","帅气","一米九"))
fun main(args: Array) {
println(mIntArray.slice(1..2)) //分割运算符,取1到2 位,返回一个区间:IntRange
for (i in mIntArray){ //遍历数组中的元素
println(i)
}
}
输出结果:
[4, 6]
2
4
6
8
10

关于for循环,之后的文章讲到语法再讲解。

可空类型

可空类型主要是为了从编译层面尽可能的减少NPE。

在Kotlin中申明一个变量,如果类型后面不加?则不能直接给此变量赋值为null,在类型后面加上?就变成了可空类型,而可空类型可以直接赋值为null。

var name: String = null//Error:Null can not be a value of a non-null type String
var name1: String? = null//可空类型,可以赋值为null

可空类型与普通类型的区别,主要体现在两个运算符上,也就是?. 和 !! 。

我们使用Java编码时,是不是经常觉得烦透了?用个参数要判空,用个数组要判空,用个类要判空,真是烦死了!!!

《Kotlin入门与进阶:基础知识(二)类、对象、数组、区间》

但是!!!在Kotlin中,这种操作真是小菜一碟。

看代码示例,只需一个操作符:

fun main(args: Array) {
var name: String = "liuliqianxiao"
print(name.length)//正常使用即可,因为是非空类型,可以放心使用,不用判断if(name != null)
var name1: String? = null//可空类型,可以赋值为null
//这么调用时错误的
// print(name1.length)//Error:Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
//传统用法
if(name1 != null){
print(name1.length)
}
//kotlin风格的用法
print(name1?.length) //当name1是null时,会输出null
//或者这么使用
print(name1!!.length)//当name1是null是报npe错误
}

参数为可空类型,比如val name: String = null,

但调用了(name.length ?.length)时,若参数为空,只会返回null,而不会抛出空指针异常。

class 人() {
var userName: String? = null
}
fun main(args: Array) {
var user: 人? = null
print(user?.userName?.length)//user==null 或者 userName==null都会输出null
}

智能类型转换与安全类型转换

在Java 中,类型转换是可能抛出类型转换异常的,一旦发生这种状况,就可能导致程序奔溃,app直接crash。

比如 子类转化为父类:

val sub:SubClass = parent as SubClass

若类型不合,程序崩溃

但在Kotlin中:

val sub:SubClass? = parent as?SubClass

假如转换失败,不会抛出异常,而是返回null,这样可以避免崩溃,多了很多处理余地

而智能类型转换又是什么机制呢?

就是,在Java 中:

Parent parent = new Child();//Child 中有getName()方法,但父类Parent中没有
if(parent instanceof Child){
String name = ((Child)parent).getName();
}

是不是感觉超级麻烦?明明我都知道parent是Child类型了,要调用Child的方法,还得先把Parent转化为Child类型。

而在Kotlin中:

val parent:Parent = Child()
if(parent is Child){
var name:String = parent.getName()
}

编译器自行推到类型,而我们无需在代码层面做无用功。

本篇文章主要讲解了类与对象,数组与区间,可空类型与类型转换,下一篇开始讲解Kotlin语法。

若有疑问或者本篇文章有谬误之处,欢迎留言探讨。

 


推荐阅读
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 本文介绍了在多平台下进行条件编译的必要性,以及具体的实现方法。通过示例代码展示了如何使用条件编译来实现不同平台的功能。最后总结了只要接口相同,不同平台下的编译运行结果也会相同。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了在Java中gt、gtgt、gtgtgt和lt之间的区别。通过解释符号的含义和使用例子,帮助读者理解这些符号在二进制表示和移位操作中的作用。同时,文章还提到了负数的补码表示和移位操作的限制。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
author-avatar
手机用户2502902093
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有