继承与重写
- kotlin所有的类默认都是被final修饰的,不能被集成想要被集成需要用到open关键字
- kotlin默认所有的方法也是final修饰的,想要被重写可以使用open修饰
open class Father(var name: String) {
private fun showName() {
println("父方法" + this.name)
}
open fun myname() {
println(this.name)
}
}
class Son(var names: String) : Father(names) {
override fun myname() {
println("子方法" + this.names)
}
}
fun main() {
var person: Father = Son("老黑")
println(person.myname())
}
类型判断和类型转换
- 类型判断
var person: Father = Son("老黑")
println(person is Father)
println(person is Son)
println(person is File)
- 类型转换
var person: Father = Son("老黑")
println(person is Father)
println(person is Son)
println(person is File)
if(person is Father){
(person as Father).showName()
}
if(person is Son){
(person as Son).showName()
}
Any
- Any类似Java中的Object,只提供标,看不到实现,实现在各个平台处理好了,Kt中的任何类都继承了Any
object关键字
- object修饰的类,只会有一个示例,类似单例
package com.fyx.s1
import sun.plugin.dom.core.Text
//构造器执行顺序,init相当于java的构造器{}
object KtBase2{
init {
println("构造执行了")
}
fun show(){
println("修饰单例模式")
}
}
fun main() {
println(KtBase2)
println(KtBase2)
println(KtBase2)
println(KtBase2)
println(KtBase2.show())
}
对象匿名
- 使用object写法
open class Person {
open fun showmyTest(name: String) {
println("原始函数")
}
}
fun main() {
var name: Person = object : Person() {
override fun showmyTest(name: String) {
println("匿名构造")
}
}
name.showmyTest("老黑")
}
伴生对象
- 因为kotlin没有static静态关键字,所以使用 companion object 来表示
- 无论对象构建多少次,伴生对象只存在一次
- 伴生对象只会初始化一次
class Person {
companion object {
var configUrl = "http://baidu.com"
}
}
fun main() {
println(Person.configUrl)
}
内部类和嵌套类
- 使用inner修饰内部类可以实现内部类访问外部类,且外部类也可以访问内部类
class Body {
var name = "身体"
//外访问内
var heartname = Heart().heartsname
inner class Heart() {
var heartsname = "心脏"
//内访问外
fun showName() {
println("我的信息是$name")
}
}
}
- 默认不使用inner就是嵌套类,只能外部类访问内部类,不可内部类访问外部类
class Body {
var name = "身体"
//外访问内
var heartname = Heart().heartsname
class Heart() {
var heartsname = "心脏"
//内访问外
fun showName() {
//报错
println("我的信息是$name")
}
}
}
普通类和数据类
- 普通类就是使用class修饰的类(会根据构造生成默认的字段和get,set 方法)
- 数据类是使用data class 修饰的类(会根据构造生成默认的字段和get,set 方法,结构操作和重写 copy,tostring,hashcode,equals函数)
区别就在于数据类比普通类所提供的方法多
class ResultData1(var code: Int, var mes: String, var data: String) {
}
data class ResultData2(var code: Int, var mes: String, var data: String) {
}
fun main() {
//普通类
println(ResultData1(200,"成功","一条数据"))
//ResultData1@266474c2
//数据类
println(ResultData2(200,"成功","一条数据"))
//ResultData2(code=200, mes=成功, data=一条数据)
//比较 因为没有重写equals 所以默认比较的是地址值,所以是false
println(ResultData1(200,"成功","一条数据")==ResultData1(200,"成功","一条数据"))
//false
//比较 因为没有重写equals 所以默认比较的是地址值,所以是false
println(ResultData2(200,"成功","一条数据")==ResultData2(200,"成功","一条数据"))
//true
}
结构化声明
- 结构化声明是一种简单快捷的数据取值,数据类默认是生成了结构化函数
注意:结构化函数必须命名成component1 以此类推
class ResultData1(var code: Int, var mes: String, var data: String) {
operator fun component1() = code
operator fun component2() = data
operator fun component3() = mes
}
data class ResultData2(var code: Int, var mes: String, var data: String) {
}
fun main() {
var (name, data, sex) = ResultData1(12, "描述", "数据")
println("$name$data $sex")
var (names, datas, sexs) = ResultData2(12, "描述", "数据")
println("$names$datas $sexs")
}
运算符重载
- 运算符重载plus做运算
class Math(var num1: Int, var num2: Int) {
operator fun plus(data1: Math): Int {
return (this.num1 + data1.num1) * (this.num2 + data1.num2)
}
}
fun main() {
println(Math(1,2) + Math(1,2))
}
枚举类型
enum class Week {
星期一,
星期二,
星期三
}
data class Info(var name: String, var size: String) {
fun show() {
println("${this.name}长度是$size")
}
}
enum class BodyInfo(private var info: Info) {
Head(Info("头", "20")),
Hand(Info("手", "30")),
Body(Info("身体", "20"));
fun show() {
println("${this.info.name} ${this.info.size}")
}
fun updateData(info: Info) {
this.info.size = info.size
this.info.name = info.name
println("${this.info.name} ${this.info.size}")
}
}
fun main() {
println(Week.星期一)
println(Week.星期三 is Week)
//常用枚举
BodyInfo.Body.show()
BodyInfo.Hand.updateData(Info("我不是手,我是胳膊","长度20公分"))
}
密封类
根据下面的代码,我们想要打印出成绩优秀的学生名字,那么使用传统的枚举是实现不了的,我们可以使用密封类(sealed)来实现
enum class Week {
S1,
S2,
S3,
S4
}
class Teacher(private var data: Week) {
fun show() =
when (this.data) {
Week.S1 -> "很差"
Week.S2 -> "及格"
Week.S3 -> "良好"
Week.S4 -> "优秀"
}
}
fun main() {
println(Teacher(Week.S1).show())
}
- 密封类的特点,所有的类都需要集成原密封类
sealed class Week {
object S1 : Week()
object S2 : Week()
object S3 : Week()
class S4(var stuName: String) : Week()
}
class Teacher(private var data: Week) {
fun show() =
when (this.data) {
is Week.S1 -> "很差"
is Week.S2 -> "及格"
is Week.S3 -> "良好"
is Week.S4 -> "优秀该学生的名字是${(this.data as Week.S4).stuName}"
}
}
fun main() {
println(Teacher(Week.S1).show())
println(Teacher(Week.S4("李雷")).show())
}
这里可能会存在疑问,为什么又成员变量的类需要使用class而不是object,因为其他类都是单例,使用object 来创建的枚举至始至终都是一个对象,而class对象的类可以是多个
接口
interface USB {
var name: String
var info: String
fun show(): String
}
class Mouse(override var name: String = "鼠标", override var info: String = "雷蛇鼠标") : USB {
override fun show(): String {
return "${this.name} 和${this.info}"
}
}
class KeyWorld(override var name: String = "键盘", override var info: String = "雷蛇键盘") : USB {
override fun show(): String {
return "${this.name} 和${this.info}"
}
}
fun main() {
println(Mouse().show())
println(KeyWorld().show())
}
抽象类
- 一些流程相似,但是内部具体实现不同的可以使用抽象类
abstract class Layout {
fun load() {
setContentView(getWeight())
this.initView()
this.initData()
this.initXXX()
}
private fun setContentView(weight: Int) {
println("我的宽度是${weight}")
}
abstract fun getWeight(): Int
abstract fun initView()
abstract fun initData()
abstract fun initXXX()
}
class AppLayOut : Layout() {
override fun getWeight(): Int {
return 100
}
override fun initView() {
println("初始话视图")
}
override fun initData() {
println("初始化数据")
}
override fun initXXX() {
println("初始化XXX")
}
fun show() {
super.load()
}
}
fun main() {
AppLayOut().show()
}
泛型
泛型就是将类型以参数的方式进行传递,从而提高代码的扩展性
//万能输出器
class DataOutm<T>(var data: T) {
fun show() {
println("万能输出${data.toString()}")
}
}
data class Person(var name: String, var age: Int) {
}
data class Foot(var name: String, var price: Double) {
}
fun main() {
var Jack=Person("老王",18)
var Apple=Foot("苹果",18.0)
DataOutm<Person>(Jack).show()
DataOutm<Foot>(Apple).show()
}
vararg 可变参数
类似与Java中的参数…
//vararg 表示可以传入任意类型的参数
class DataOutm<T>(vararg data: T, var flag: Boolean) {
//out 我们的T只能被读取,不能被修改 T只能读取
private val objdata: Array<out T> = data
//返回数据的值
public fun showData(index: Int): T? {
return objdata[index]
}
}
fun main() {
//默认的泛型是<Any>
var data=DataOutm("我是字符串",12,"I",12.01f,54.21,null ,flag = false)
println(data.showData(0))
println(data.showData(1))
println(data.showData(2))
println(data.showData(3))
println(data.showData(4))
println(data.showData(5))
}