基本的定义
- 静态语言
- 修饰符
- 函数
- 返回类型(类型推倒 Int)
- 函数的变长参数可以用 vararg 关键字
- NULL检查机制
- 类型监测以及自动类型转换
- 区间
- 比较
- When表达式
- For循环
- 循环控制 @标签
- 构造函数
- 继承
- 懒加载
- 赋值
- 设置允许为null
- 懒加载,被调用必须有值
- 接口
- 抽象类
- 继承
- POJO实体类
- 单例类(object)
- Kotlin写单例
- 内部类 (inner)
一个普通的Kotlin类定义
class ExampleUnitTest {
val name = "Name";
var age = "18";
@Test
fun main() {
val info_1: String = "A";
println(info_1)
var info_2: String = "B";
print(info_2)
}
}
通过 Kotlin
编译成javac
再看看 (Tools -- Kotlin -- show Kotlin Bytecode -- Decompile)
public final class ExampleUnitTest {
@NotNull
private final String name = "Name";
@NotNull
private String age = "18";
@NotNull
public final String getName() {
return this.name;
}
@NotNull
public final String getAge() {
return this.age;
}
public final void setAge(@NotNull String var1) {
Intrinsics.checkNotNullParameter(var1, "");
this.age = var1;
}
@Test
public final void main() {
String info_1 = "A";
boolean var2 = false;
System.out.println(info_1);
String info_2 = "B";
boolean var3 = false;
System.out.print(info_2);
}
}
结论 关于 var 和 val
- var:可以修改,并且会在
class
中自动生成get/set
函数 - val:是不能修改,是用了 java中的
final
修饰,所以只能get
静态语言
kotlin是一门静态语言,在编译期就确定了类型,并且可以类型推倒
修饰符
访问权限修饰符
修饰符 | 类成员 | 作用域范围 |
---|---|---|
public | 所有地方可见 | 所有地方可见 |
internal | 模块中可见 | 模块中可见 |
protected | 子类中可见 | 父子类 |
private | 类中可见 | 文件中可见 |
类修饰符
修饰符 | 说明 |
---|---|
final | 不能被继承 |
open | 可以被继承 |
abstract | 抽象类 |
enum | 枚举类 |
data | 数据类 |
sealed | 密封类 |
annotation | 注解类 |
inner | 嵌套类(内部类) |
seeled 密封类:
sealed class SealedExpr{
data class Person(val num1 : Int, val num2 : Int) : SealedExpr()
object Add : SealedExpr() // 单例模式
object Minus : SealedExpr() // 单例模式
}
// 其子类可以定在密封类外部,但是必须在同一文件中 v1.1之前只能定义在密封类内部
object NotANumber : SealedExpr()
- 密封类是用来表示受限的
类继承结构
,枚举enum升级版 - 不能被实例化,可以有子类被继承
- 在枚举中常量只能存在一个实例,而密封类可以存在多个实例
- 有效的保护代码,使用
when
表达式从而验证语句不用添加else
成员修饰符
修饰符 | 说明 |
---|---|
override | 重写函数 |
open | 可以被重写 |
final | 不能被重写 |
abstract | 抽象函数 |
lateinit | 延迟初始化(var) |
by lazy | 延迟初始化(vrl) |
-
lateinit 声明时候忽略初始化值,在后面用到的时候在初始化
lateinit var test: String
-
by lazy 在头次被调用,才自动设置表达式初始化
val str by lazy { println("Init lazy") "Hello World" }
泛型修饰
修饰符 | 说明 |
---|---|
in | 相当于Java中的super关键字的作用 |
out | 相当于Java中的extends关键字的作用 |
函数
返回类型 Int
fun add(number1: Int, number2: Int): Int {
return number1 + number2;
}
返回类型(类型推倒 Int)
fun add2(number1: Int, number2: Int) = number1 + number2
函数的变长参数可以用 vararg 关键字
fun lenMethod(vararg value: Int) {
for (i in value) {
print(i)
}
}
NULL检查机制
//类型后面加? 表示可为空
var age: String? = "23"
//抛出空指针异常
val ages = age!!.toInt()
//不做处理返回 null
val ages1 = age?.toInt()
//age为空返回-1
val ages2 = age?.toInt() ?: -1
kotlin在空安全设计对于声明可为空的参数,在使用要进行空判断处理,
- 字段后面加
!!
像JAVA
一样抛出异常 - 另一种字段后加
?
可不做处理返回值为NULL
类型监测以及自动类型转换
可以用is
运算检测一个表达式是否为某个类型,类型与instanceof
关键字
- Any 为 Object类型
fun getStringLength(obj: Any): Int? {
if (obj !is String)
return null
// 在这个分支中, `obj` 的类型会被自动转换为 `String`
return obj.length
}
区间
区间表达式由 ..
以 in
与 !in
组成
for (i in 1..4) print(i) // 输出“1234”
for (i in 4..1) print(i) // 什么都不输出 不支持递减区间
for (i in 4 downTo 1) print(i) //关键字 downTo 可以支持递减区间
if (i in 1..10) { // 等同于 1 <= i && i <= 10
println(i)
}
// 使用 step 指定步长
for (i in 1..4 step 2) print(i) // 输出“13”
for (i in 4 downTo 1 step 2) print(i) // 输出“42”
// 使用 until 函数排除结束元素
for (i in 1 until 10) { // i in [1, 10) 排除了 10
println(i)
}
比较
fun main(args: Array) {
val a: Int = 10000
println(a === a) // true,值相等,对象地址相等
//经过了装箱,创建了两个不同的对象
val boxedA: Int? = a
val anotherBoxedA: Int? = a
//虽然经过了装箱,但是值是相等的,都是10000
println(boxedA === anotherBoxedA) // false,值相等,对象地址不一样
println(boxedA == anotherBoxedA) // true,值相等
}
- 两个 == 表示比较两个值大小
- 三个等号 === 比较对象地址
When表达式
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // 注意这个块
print("x 不是 1 ,也不是 2")
}
}
When in (!in) 区间
when (x) {
in 1..10 -> print("x is in the range")
in validNumbers -> print("x is valid")
!in 10..20 -> print("x is outside the range")
else -> print("none of the above")
}
For循环
方法一(区间)
var items = listOf("A", "B", "C", "D", "E", "F")
//方法一
for (item in items){
println(item)
}
方法二(闭包)
//方法二
items.forEach {
println(it)
}
方法三(下标迭代)
//方法三
for (index in items.indices){
println("下标: ${index} ,对应的值为: ${items[index]}")
}
循环控制 @标签
loop@ for (i in 1..20) {
for (j in 1..20) {
println("i:${i} j:${j}")
if (i == 5)
break@loop
}
}
可以通过 @xxx 自定义标签,break@xxx
退出循环
构造函数
构造函数由 主构造 & 次构造 constructor, 次构造必须调用主构造
class Person(id: Int) { //主构造
constructor() : this(id = 1) { //次构造
}
constructor(id: Int, name: String) : this(id) { //次构造
}
constructor(id: Int, age: Int) : this(id) { //次构造
}
}
通过编译文件查看
public final class Person {
public Person(int id) {
}
public Person() {
this(1);
}
public Person(int id, @NotNull String name) {
Intrinsics.checkNotNullParameter(name, "name");
this(id);
}
public Person(int id, int age) {
this(id);
}
}
继承
默认为 final
不能被继承, 所以父类需要被其他子类继承 加上关键字 open
open class Person(id: Int) { //主构造
}
class Student : Person(10) { //student 继承了 Person
}
懒加载
kotlin 变量一律没有默认值,
val name: String ; //报错, kotlin 变量一律没有默认值
有三种方式处理
赋值
val name: String = "Neng";
设置允许为null
val name: String? = null;
懒加载,被调用必须有值
val name: String? = null;
接口
关键字: interface , 默认是 public
interface Callback {
fun callBackMethod(): Boolean
}
抽象类
关键字:abstract , 默认是 open,也就是 public
abstract class Person {
}
继承
- 抽象类
abstract class Person : Callback { //实现了 Callback
//在抽象类里面, 可以选择实现或者是不实行, 如果是普通类必须实现
// override fun callBackMethod(): Boolean {
// TODO("Not yet implemented")
// }
abstract fun getLayoutId(): Int;
abstract fun initVIew();
}
- 普通类
class Student : Person() {
override fun getLayoutId(): Int {
TODO("Not yet implemented")
}
override fun initVIew() {
TODO("Not yet implemented")
}
override fun callBackMethod(): Boolean {
TODO("Not yet implemented")
}
}
POJO实体类
关键字: data
data class User (val name:String ,val age: Int, val set:Char, val isSHow: Boolean)
自动生成常用的函数
编译成java看看
public final class User {
@NotNull
private final String name;
private final int age;
private final char set;
private final boolean isSHow;
@NotNull
public final String getName() {
return this.name;
}
public final int getAge() {
return this.age;
}
public final char getSet() {
return this.set;
}
public final boolean isSHow() {
return this.isSHow;
}
public User(@NotNull String name, int age, char set, boolean isSHow) {
Intrinsics.checkNotNullParameter(name, "name");
super();
this.name = name;
this.age = age;
this.set = set;
this.isSHow = isSHow;
}
@NotNull
public final String component1() {
return this.name;
}
public final int component2() {
return this.age;
}
public final char component3() {
return this.set;
}
public final boolean component4() {
return this.isSHow;
}
@NotNull
public final User copy(@NotNull String name, int age, char set, boolean isSHow) {
Intrinsics.checkNotNullParameter(name, "name");
return new User(name, age, set, isSHow);
}
// $FF: synthetic method
public static User copy$default(User var0, String var1, int var2, char var3, boolean var4, int var5, Object var6) {
if ((var5 & 1) != 0) {
var1 = var0.name;
}
if ((var5 & 2) != 0) {
var2 = var0.age;
}
if ((var5 & 4) != 0) {
var3 = var0.set;
}
if ((var5 & 8) != 0) {
var4 = var0.isSHow;
}
return var0.copy(var1, var2, var3, var4);
}
@NotNull
public String toString() {
return "User(name=" + this.name + ", age=" + this.age + ", set=" + this.set + ", isSHow=" + this.isSHow + ")";
}
public int hashCode() {
String var10000 = this.name;
int var1 = (((var10000 != null ? var10000.hashCode() : 0) * 31 + this.age) * 31 + this.set) * 31;
byte var10001 = this.isSHow;
if (var10001 != 0) {
var10001 = 1;
}
return var1 + var10001;
}
public boolean equals(@Nullable Object var1) {
if (this != var1) {
if (var1 instanceof User) {
User var2 = (User)var1;
if (Intrinsics.areEqual(this.name, var2.name) && this.age == var2.age && this.set == var2.set && this.isSHow == var2.isSHow) {
return true;
}
}
return false;
} else {
return true;
}
}
}
单例类(object)
object MyEngine {
fun method() {
println("单利class,methid函数")
}
}
Kotlin写单例
class NetManager {
object Holder {
val instance = NetManager();
}
//派生字段, 相当于 java static 关键字
companion object {
fun getInstance(): NetManager = Holder.instance;
}
fun show(name: String) {
println(name)
}
}
fun main() {
NetManager.getInstance().show("kt")
}
内部类 (inner)
class Test {
val I = "AAAA"
class Sub {
fun show() {
// print("拿到变量:${I}") //拿不到 I , kotlin 不是类部类,而且嵌套类
}
}
inner class Sub2 {
fun show() {
print("改成类部类 关键字 inner ${I}")
}
}
}