Kotlin-Android世界的一股清流-Class类
源码地址:https://github.com/cn-ljb/KotlinBlogs
类的定义
Kotlin中的类也是使用class关键字定义
但整个类结构与Java有所不同:Kotlin中类的定义主要由三部分组成:类名、类头、类主体。
// 类名 类头
class Person(var name: String) {//...类主体}
一、类名
同Java紧跟class关键字之后,空格隔开
二、类头
两部分组成:
- 成员属性
- 主构造函数
代码示例:
class Person(var name: String) {init {println("属性已被初始化:$name")println("主构造额外操作")}}
name是Person类的一个成员属性,小括号()是Person类的主构造方法。也就是说Kotlin中在创建Person类对象时,必须传入name属性值,并且会自动为其初始化,帮我们做了类似Java里this.name = name的操作。
如果我们的主构造除了初始化属性之外,还有别的代码操作,需要把这些操作放到init()函数中,Kotlin的主构造函数在初始化属性之后,会调用该函数。
调用:
Person("Jack")
输出:
属性已被初始化:Jack
主构造额外操作
三、类主体
类主体部分类似于Java(大括号里的东西),但也有所不同,前面的主构造额外函数init()也属于类主体区域内。
类主体可以包含:
- 构造函数和初始代码块
- 成员属性
- 成员函数
- 内部类
- 伴生对象
- 对象声明
1、构造函数
除之前的主构造函数和init()函数外,Kotlin也支持多构造函数,其它的构造函数称为二级构造函数
constructor (name: String, age: Int) : this(name) {this.age = age
}
这里,Kotlin定义二级构造函数与Java不同:
- 仅需constructor关键字修饰,不需要函数名
- 所有的二级构造必须先调用(代理)主构造,主构造执行完后,会执行二级构造中的代码
所以我们仅在二级构造中初始化了age属性,name属性已由之前的主构造初始化。
如果我们没有定义构造函数(主\二级),JVM虚拟机依旧会为我们提供一个无参构造函数,这和Java一样;但是,如果我们的主构造参数设置了默认值,Jvm虚拟机也会为我们提供一个无参构造。
//主构造存在默认参数,JVM依旧会提供一个无参构造
class Person(var name: String = "无名") {//...
}
所以我们可以使用默认值直接创建Person对象
val wuMing = Person()
(注:虽然我们已经创建过很多次对象了,但还是提下Kotlin创建对象是不需要new关键字的)
2、成员属性
首先概念上是同Java的成员变量一样的,我们还是单独来说说它的区别和特点
Kotlin支持可变属性和只读属性,什么意思呢?类似于Java中常量和变量的概念
val关键字:只读属性,初始化后,只能访问,不能赋值
var关键字:可变属性,可读可写
getter()\setter()
讲到属性,不能少了JavaBean里的getter()\setter()方法,虽然Java的IDE基本都提供了自动生成代码的快捷选项,但Kotlin将其再一步简化
Kotlin中如果属性是var可变属性,那么默认就提供getter()\setter()函数,val则提供getter()函数
如果我们需要覆写这些getter()\setter()方法只需遵循以下格式:
var <propertyName>: <PropertyType> [ = <property_initializer> ]<getter><setter>
我们尝试修改age属性的getter()方法,不同年龄段,返回不同的数字:
var age: Int = 0get() {if (field < 16) {return 0} else if (field in 16..30) {return 1} else return 2}
调用:
val per = Person("Jack", 10)println(per.age) //输出0
等等,getter()里的field是什么?备用字段
为什么我们不直接比较age而是用field关键字呢?
因为在Kotlin中规定,如果直接使用属性名,那么就相当于调用它的getter()函数,所以如果我们在getter函数里直接使用age属性,那么这将是一个无限的递归,JVM自然会抛出 栈溢出。
为了解决这个问题Kotlin在getter()和setter()函数中为我们提供了这个备用字段field
3、成员函数
在函数章节提到过,无论是定义,使用,作用域都同Java,暂一笔带过。
4、内部类
Kotlin中对于内部类的定义有所不同,在Kotlin中内部类除了必须定义在类的内部外,还必须通过inner关键字修饰,否则它只是个嵌套类。
探讨内部类和嵌套类各自的特点:
A是外部类,B是A的嵌套类,C是A的内部类,我们尝试互相访问对方的属性以及函数。
外部类访问嵌套类以及内部类中的资源,我们在A类中添加tell()函数测试:
以上代码中可以得出结论:外部类是无法直接访问嵌套类或者内部类中的任何资源
那么嵌套类能访问外部类资源吗?我们给嵌套类也加上tell()函数
很显然嵌套类是不能直接调用外部类资源以及内部类资源
再来看看内部类:
Kotlin中的内部类跟Java一样是可以直接访问外部类资源,但不能访问嵌套类资源
最后,嵌套类、外部类是如何创建对象的:
//嵌套类创建对象
val b = A.B()//内部类创建对象
val c =A().C()
嵌套类创建对象,需要指定外部类前缀;而内部类创建对象则需要通过外部类对象来创建
细心的朋友可能已经发现这两种书写格式在Java中很眼熟,内部类的创建格式与Java相同就不说了,这个嵌套类与Java的(static)静态内部类创建语法是一样的。
如果真如我们猜想的那样,Java中的静态内部类,可以访问直接外部类中static修饰的全局变量;Kotlin中的嵌套类我们不妨测试一下。(Kotlin中的全局变量通过伴生对象定义,这个之后会讲,先知道它就是全局变量即可)
我们发现嵌套类可以调用该变量
所以可以得出:Kotlin中的嵌套类的使用场景是类似与Java中的静态内部类的使用场景。
5、伴生对象
前面也提到了Kotlin中是没有static关键字的,但是总得有东西来替代它,那么它就是伴生对象。
从名字来看它貌似是随着类一起出生的,它和Java中static的定义也很相似(当类加载时static修饰的属性和方法就直接加载到内存中)。
使用起来也和Java中是一样的,可以直接通过类名调用,还有伴生对象只能使用伴生对象中的属性及方法,就如同static修饰的方法只能调用static修饰的属性和方法一样。
6、对象声明与表达式
单例设计模式大家一定再熟悉不过,如果在Java中,肯定首要是创建一个类,然后私有化构造方法等等,Kotlin中提供了更简便的实现方案。你不是仅需一个对象吗,那么干嘛要创建类,直接创建一个对象不是更好。
Kotlin中支持直接创建对象,称为:对象声明 ,使用object关键字修饰。
我们在之前的Person类中声明一个obj对象
那么这个对象对于Person来说就像一个全局的只读变量一样
当然你完全可以不用写在类的内部,只是要知道类的主体里可以写对象声明的
对象表达式又是什么?
Java中的匿名内部类,想必做android开发的同学再熟悉不过,那么Kotlin中的匿名内部类就叫做对象表达式。
既然类似Java中的匿名内部类,那么使用场景肯定也是类似的了。
这段代码想必大家都很熟悉,为Button设置点击事件的回调,用Java代码实现最直接的方法便是创建个匿名内部类对象,那么我们来看看Kotlin的对象表达式
我只能说实在是不能再像了(与Java匿名内部类相比)。
唯一的区别就在于,对象表达式可以直接访问局部作用域里的变量,不需要像java那样final修饰才行。
四、数据类
最后再讲讲一种特殊的类:数据类
前面属性时,提到了JavaBean的概念,提供getter()和setter()函数,除了这两个函数之外equals()、toString()等也是几个常用函数,那么Kotlin中为了开发方便,直接提供data关键字来修饰这些数据类。
使用data修饰的类,除了之前var\val提供的setter()\getter()函数之外,还默认实现了
equals()/hashCode 函数
toString 格式是 "User(name=john, age=42)"
[compontN()]
copy() 函数
如果在类中明确声明或从基类继承了这些方法,编译器不会自动生成。
为确保这些生成代码的一致性,并实现有意义的行为,数据类要满足下面的要求:
- 主构造函数应该至少有一个参数;
- 主构造函数的所有参数必须标注为 val 或者 var ;
- 数据类不能是 abstract,open,sealed,或者 inner ;
- 在 JVM 中如果构造函数是无参的,则所有的属性必须有默认的值。
例如:
data class Data(var data1: String, var data2: String)
Kotlin-Android世界的一股清流-Class类相关推荐
- Kotlin-Android世界的一股清流
这系列文章是做什么的? 是本人学习完Kotlin编程语言后,尝试的一次总结笔记.主要记录Kotlin语言与Java语言的不同之处,所以阅读这系列文章时,可能需要先具备一些简单的Java基础. 源码地址 ...
- Kotlin-Android世界的一股清流-函数
源码地址:https://github.com/cn-ljb/KotlinBlogs 函数定义 什么是函数-不用解释了吧- 函数范围 Kotlin 中可以在文件顶级声明函数,这就意味者你不用像在Jav ...
- Kotlin-Android世界的一股清流-Package
源码地址:https://github.com/cn-ljb/KotlinBlogs Package 命名规则(同Java) 由小写字母.下划线.数字组成,必须由小写字母或者下划线开头 行业规范,同J ...
- Kotlin-Android世界的一股清流-委托
源码地址:https://github.com/cn-ljb/KotlinBlogs 委托 一.委托类 什么是委托类? 代理设计模式,在Java中实现一个简单的代理模式如下: //抽象功能 publi ...
- Kotlin-Android世界的一股清流-Lambda表达式
(转载) 源码地址:https://github.com/cn-ljb/KotlinBlogs 什么是Lambda表达式 在函数的篇章里我们知道了Lambda表达式就是函数,并且也进行了证明. 这篇文 ...
- Kotlin-Android世界的一股清流-流程控制
源码地址:https://github.com/cn-ljb/KotlinBlogs 流程控制语句 if语句 基本用法同Java 唯一不同点,Kotlin中没有三目运算符(a==xxx?b:c),取而 ...
- tcl 950 android 7,TCL 950测评:商务旗舰手机界的一股清流
TCL在国内消失了三年.这三年是国内手机厂商你争我夺得最为惨烈的三年.等它杀回来的时候这个市场早已杀红了眼.而以"宛如生活"这样的品牌定调又与国内大多数的厂商的风格都不太一样,更加 ...
- App 界的一股清流 音视频应有尽有 完全按照 Material design 规范设计的 App
vld 项目地址:Cuieney/vld 简介:App 界的一股清流 音视频应有尽有 完全按照 Material design 规范设计的 App 更多:作者 提 Bug 标签: andr ...
- Kotlin Android Studio 环境搭建
Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,被称之为 Android 世界的Swift,由 JetBrains 设计开发并开源. Kotlin 可以编译成Java字节码,也可以编 ...
最新文章
- 【干货】CNN与Transformer的强强联合!谷歌最新开源BoTNet,ImageNet达84.7%准确率
- 互联网架构为什么要做服务化
- asp.net 开发疑问?
- 002_ZooKeeper安装配置
- 【转】Linux查看文件编码格式及文件编码转换
- mac redis 客户端_分享一个免费好用的Redis桌面客户端
- AndroidStudio安卓原生开发_UI高级_Shape的使用_虚线_直线_矩形_渐变_径向渐变_线性渐变_扫描渐变---Android原生开发工作笔记122
- python画图小实例_python绘图实例
- python_scrapy_爬虫
- 百度地图获取行政区划边界
- Layui的管理系统的模板
- python 判断数字是奇数还是偶数
- C#绘制中国象棋棋盘
- matlab normx-x0_【 MATLAB 】norm ( Vector and matrix norms )(向量范数以及矩阵范数)
- Android给文件改后缀名
- (附源码)计算机毕业设计SSM旅游足迹分享系统
- 使用LINUX云服务器搭建web、小程序服务器MySql+Java+Tomcat
- CSDN常见问题汇总
- oracle 数据库存储过程编译报错PLS-00103出现符号 end-of-file在需要下列之一时
- 【稳定性day3】蘑菇街的运维体系 - 如何撑住双十一