类与对象
类是一个抽象的概念,是具有某些特征的事物的概括,并不代指任意具体的事物,而对象是一个具体的概念,与类相对,用来描述某一种类的具体个体。
比如:“人” 是一个类,而 “一个三十五岁,身高一米八,慈眉善目的男工程师”则是这个类的一个对象。
在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<String>) { val 女仆:美女 = 美女("暴怒","慈祥","一米三") val 兽人:帅哥 = 帅哥("狂暴","惊悚","三米") }
open修饰“人”这个类,表示这个类可以被继承,在Kotlin中,所有的类默认都是“final”的,不可以被继承。
一个类通常可以有很多个具体的对象,但一个对象本质上只能从属于一个类。
子类拥有父类一切特征,也可以定义自己的特征
所有的类最终继承自Any
关于“继承”,“父类”和“子类”的概念,与Java基础知识无异,在此不做赘述。
“人”包含三个属性:长相,性格,身高,Kotlin每个类有自带的init()方法,在新建类的时候会自动调用。
子类与父类之间通过 :来继承。
可以看到,新建子类时 , val 女仆:美女 = ... 跟定义基本类型 val mInt:Int = ... 形式上其实是一样的,
在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。。。兄弟,高中《代数》了解一下。
示例:
val mIntRange:IntRange = 0 until 100un main(args: Array<String>) { println( 1 in mIntRange) } 输出结果 : true
数组
也就是我们常说的 “Array”。
数组的英文定义是:
An impressive display or range of a particular type of thing or an ordered arrangement ,in partucular.
有看到一个“数”字吗? 所以“数组”跟“数” 实际上并没有什么关系。数组其实是一系列的对象。
在Kotlin中,数组的基本写法是(以String为例):
val array:Array[String] = arrayOf(...)
数组的一些基本操作:
arrayp[i] 第i个成员
array[i] = "wakaka" 给第i个成员赋值
array.length 数组长度
跟Java无区别。
在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<String>) { println(mIntArray.slice(1..2)) //分割运算符,取1到2 位,返回一个区间:IntRange for (i in mIntArray){ //遍历数组中的元素 println(i) } } 输出结果: [4, 6]246810
关于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中,这种操作真是小菜一碟。
看代码示例,只需一个操作符:
fun main(args: Array<String>) { 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<String>) { 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() }
作者:请抱抱陈先生
链接:https://www.jianshu.com/p/adc2598ea44a
共同学习,写下你的评论
评论加载中...
作者其他优质文章