介绍:在Kotlin中类可以包含:构造函数和初始化代码块,函数,属性,内部类,对象声明. 使用的关键字和java是一样的使用class进行声明
实例:
代码语言:javascript复制class Demo2 { //类名为Demo2
//类里面的 函数,属性,内部类,声明等
fun foo(){ //创建成员函数
print("Foo")
}
}
如果是对js有点熟悉的同学,应该对fun指令很眼熟
类似于js的function 关键字.
构造方法
介绍: Kotlin之中一个类可以有一个主构造器以及多个次构造器.
实例:
代码语言:javascript复制class Person constructor(firstName:String){
init{
//主构造函数,创建后会执行该方法
}
}
其中关于constructor
关键字在主构造器之中一般是可以省略的
其他的子构造器之中需要添加该关键字进行定义
如果一个类有主构造器(ps:类名后面添加了括号).那么每个子构造器都要直接或者间接使用主构造器.也就是使用this
关键字代理主构造器方法.
实例1:
代码语言:javascript复制//创建了空值传递的主构造器
class Demo3(){
//子构造器就必须加上 this()
constructor(name:String):this(){
}
}
class Demo4{
constructor(name:String){
println("name:${name}")
}
}
//定义构造方法 私有 不允许有公共的构造函数
class Demo5 private constructor(){
}
实例2:
代码语言:javascript复制class Person(firstName: String) {
init {
println("firstName:${firstName}")
}
constructor(firstName: String, url: String) : this(firstName) {
println("url:${url}")
}
constructor(name: String, time: Int) : this(name) {
println("Time:${time}")
}
}
fun main(array: Array<String>) {
//Kotlin之中 创建对象 没有New关键字
var person1 = Person("Z同学")
var person = Person("Z同学", "https://zinyan.com/")
var person2 = Person("Z同学", 123)
}
输出结果:
代码语言:javascript复制firstName:Z同学
firstName:Z同学
url:https://zinyan.com/
firstName:Z同学
Time:123
其实本质和java 的构造函数以及冲突检测是差不多的.不能允许相同传参的构造函数
只是相对于java的构造函数,Kotlin有一个主构造器的概念相对于java对构造函数的控制性更强而已.
如果我们要在主构造器创建时进行初始化操作,那么我们直接在init{}
函数里面实现我们的逻辑即可.
其他情况:如果我们需要将构造器之中的函数定义为类的全局属性
很简单,添加上var
就能够在类的其他函数之中调用了
实例:
代码语言:javascript复制class Person(var firstName: String) {
fun test() {
firstName = "name"
}
}
属性定义
介绍: 定义类的属性值,通常有两个关键字 分别是var
和val
var: 声明的属性是可以在之后函数调用之中进行修改的.
varl:声明的属性,在赋值之后是不能进行修改的. 你可以参照java 的final
关键字修饰的属性.
实例:
代码语言:javascript复制class Demo2 { //类名为Demo2
//类里面的 函数,属性,内部类,声明等 添加了?号才能允许null值存在.
private var name: String? = null //一样存在private 私有
var url: String = ""
var height: Int=0
val max:Int =100
}
在Kotlin之中 创建对象时不用添加new
字段.因为Kotlin之中没有new关键字.
实例:
代码语言:javascript复制fun main(array: Array<String>){
//Kotlin之中 创建对象 没有New关键字
var temp=Demo2()
temp.url="https://zinyan.com/"
temp.height=170;
temp.name="Z同学"
}
上面都是关于非空的属性定义.
如果我们要初始化时定义属性值空那么该如何处理?
Kotlin提供了一种可以延迟初始化的方案,使用lateinit 关键字来描述属性.
实例:
代码语言:javascript复制class Test(){
lateinit var name: String
fun setUp(value:String){
name=value
}
}
fun main(array: Array<String>) {
var test = Test()
test.setUp("Z同学")
println("name:${test.name}")
}
输出:
代码语言:javascript复制name:Z同学
getter 和setter函数
介绍:通常情况下var定义的类都有默认的geter
和setter
.如果定义为val
标签额属性那么它将没有set
函数
我们也可以根据需求,进行重构属性的getter
和setter
函数
实例1:
代码语言:javascript复制class Person() {
var lastName: String = ""
get() = field.uppercase()// 将变量赋值后转换为大写
}
fun main(array: Array<String>) {
var person = Person()
//针对lastName 参数进行了修改.
person.lastName = "zinyan"
//调用了lastName 的get方法会
println("LastName:${person.lastName}")
}
输出:
代码语言:javascript复制LastName:ZINYAN
field
在方法之中的意思就是lastName. 因为getter,和setter之中 不能直接使用lastName
如果我们将方法替换后
实例2:
代码语言:javascript复制class Person() {
var lastName: String = ""
get() = lastName.uppercase()// 将变量赋值后转换为大写
}
fun main(array: Array<String>) {
var person = Person()
//针对lastName 参数进行了修改.
person.lastName = "zinyan"
//调用了lastName 的get方法会
println("LastName:${person.lastName}")
}
输出:
就会错误了.
在Kotlin之中,这个定义方式叫做BackingFields(后端变量). 使用field关键字声明.
field 关键词只能用于属性的访问器.也就是getter
和setter
函数里面
实例3:
代码语言:javascript复制class Person() {
var no: Int = 100
get() = field //其实这个可以省略
set(value) {
if (value < 10) { //如果传入的值小于 10 返回该值
field = value
} else {
field = -1 // // 如果传入的值大于等于 10 赋值为-1
}
}
var height: Float = 170.0f
private set //将属性的set方法设置为私有模式 外部禁止修改
}
fun main(array: Array<String>) {
var person = Person()
person.no = 9
println("No:${person.no}")
person.no =20
println("No:${person.no}")
println("Height:${person.height}")
输出:
代码语言:javascript复制No:9
No:-1
Height:170.0
关于getter 和setter 方法的基本情况就是这些了.
默认没有写的时候,Kotlin编译器会自动给我们补上. 例如下面的这种.
代码语言:javascript复制var dem: String = ""
get() = field
set(value) {
field = value
}
抽象类(关键字:abstract)
介绍:抽象是面向对象编程特征之一.在Kotlin之中申明抽象类或者函数使用关键字abstract
定义概念和java 的抽象类和抽象方法一样.不用进行具体的实现.
实例:
代码语言:javascript复制abstract class Demo6 {
open abstract fun text(str: String)
}
class dd : Demo6() {
override fun text(str: String) {
TODO("Not yet implemented")
}
}
继承了Demo6 抽象类,所以需要实现里面的方法
抽象类默认情况下是public 的可以被直接继承.如果非抽象类我们需要'open'关键字进行标注,才能进行继承.
嵌套类
介绍:和java的嵌套类是一样的,我们可以在class里面写嵌套类.
实例:
代码语言:javascript复制class Demo7{
private var name:String="ZZ"
class TT{
fun text()=2
}
}
fun main(array: Array<String>) {
var demo =Demo7.TT();
println("结果:${demo.text()}")
}
输出:
代码语言:javascript复制结果:2
内部类(关键字 inner)
介绍: 实现步骤和嵌套类是一样的,只是内部类添加了inner关键字进行修饰.
但是已经有嵌套类了.为什么还有一个内部类?
因为内部类会带有一个对外部类的对象的引用.所以内部类是可以直接访问外部类的属性和函数.
实例:
代码语言:javascript复制class Demo8 {
private var name: String = "ZZ"
inner class TT {
fun nameStr()=name //可以直接获取外部类属性
fun text() {
println(this@Demo8.name)//通过注解得到外部类对象
}
}
}
fun main(array: Array<String>) {
var demo = Demo8().TT() //这里有别于嵌套类的实现
demo.text()
println( demo.nameStr())
}
输出:
代码语言:javascript复制ZZ
this后添加的@XXX 主要是为了消除歧义.因为嵌套类本身有自己的this. 加上@可以告诉编译器当前使用的外部类对象的this.
匿名内部类
介绍:使用对象表达式来创建匿名内部类:
实例:
代码语言:javascript复制class Demo9{
var tt="随便的属性"
fun setTT(test:TestInterFace){
test.test()
println(tt)
}
}
interface TestInterFace{
fun test()
}
fun main(array: Array<String>) {
var test = Demo9();
test.setTT(object :TestInterFace{
override fun test() {
println("对象表达式创建匿名内部类的实例")
}
})
}
输出:
代码语言:javascript复制对象表达式创建匿名内部类的实例
随便的属性
其实匿名内部类,就如同我们在java 之中给函数传递对象时,我们直接new一个新对象传进去一样的.
只是Kotlin必须使用object
关键字而已
修饰符
介绍:类的修饰符主要分为两个种类,一种是类属性修饰符(classModifier),一种是访问权限修饰符(accessModifier)
类属性修饰符: 标识类本身的特性
关键字 | 介绍 | 备注 |
---|---|---|
abstract | 抽象类 | 抽象类默认可以继承.不用额外添加open |
final | 类不可以继承 | 普通类默认不可被继承 |
enum | 枚举类 | |
open | 类可以被继承 | 添加标注之后就可以被继承了 |
annotation | 注解类 |
访问权限修饰符:标注类或者属性的访问权限
关键字 | 介绍 |
---|---|
private | 私有,仅当前类或同一个文件可访问 |
protected | 保护,在同一个类或者子类之中可访问 |
public | 公共,全部地方都可访问 |
internal | 内部,在同一个模块下可访问 |
Kotlin的关键字其实和java之中有很多的相识之处.特别是权限访问修饰符.