Kotlin面对对象简介

Android  Kotlin  2024年9月3日 am9:46发布1个月前更新 91es.com站长
153 0 0

前言

简单介绍一下Kotlin面对对象简介。记录一下,方便自己查阅。

正文

类就是具备某些共同特征的实体的集合,它是一种抽象的数据类型,它是对所具有相同特征实体的抽象。

Kotlin中所有类都继承Any类,它是所有类的父类,如果一个类在声明时没有指定父类,则默认父类为Any类

无参数和有参数类
//不带参数[1,2,3等同]
//1
class Person1 {
}
//2
class Person2() {
}
//3
class Person3 constructor() {
}
//带参数[1和2等同]
//1
class Person1 constructor(name: String, age: Int) {
}
//2
class Person2(name: String, age: Int) {
}
继承

当继承某个类时,需要在这个类的前面加上open关键字。

open class Person1 {
}
open class Person2(name: String, age: Int) {
}
//子类继承父类
class Student1:Person1(){
}
class Student2(name: String, age: Int):Person2(name, age){
}

一个类只能继承一个父类,不能继承多个父类。

方法重写

被重写的方法,也需要open。

open class Person {
    open fun askHello(){
    }
}
class Student:Person(){
    override fun askHello() {
    }
}
抽象类

抽象方法使用abstract关键字修饰,该方法没有方法体,在使用时需要实现其方法体,当一个类中包含了抽象方法,该类必须使用abstract关键字定义为抽象类。

  1. 包含抽象方法的类必须声明为抽象类,但抽象类可以不包含任何抽象方法。

  2. 抽象类是不可以被实例化的,因为抽象方法是没有方法体的,不可以被调用。

abstract class Person {
    abstract fun askHello()
}
class Student:Person(){
    override fun askHello() {
    }
}
接口

如果一个抽象类中的所有方法都是抽象的,则可以将这个类用另外一种方式来定义,即接口。

接口是一个特殊的抽象类,在定义接口时,需要使用interface关键字来声明。

interface IPlay{
    fun onPlay()
}
class Student:IPlay{
    override fun onPlay() {
    }
}
  1. 接口中的方法都是抽象的,不能实例化对象

  2. 当一个类实现接口时,如果这个类是抽象类,则实现接口中的部分方法即可,否则需要实现接口中的所有方法。

  3. 一个类通过冒号(:)实现接口时,可以实现多个接口,被实现的多个接口之间要用逗号隔开。

  4. 一个接口可以通过冒号(:)继承多个接口,接口之间用逗号隔开。

常见类
嵌套类

Kotlin中的嵌套类是指可以嵌套在其他类中的类,该类不能访问外部类的成员,内部类指的是可以用inner标记以便能够访问外部类的成员。

class OutClass{
    var name:String = "91大神"
    class InClass{
        fun print(){
            //error,无法访问name
            //Log.d(TAG, "print:$name ")
        }
    }
}
内部类

内部类只需要在嵌套类的基础上添加一个“inner”关键字即可,将其标识为内部类。

class OutClass{
    var name:String = "91大神"
    inner class InClass{
        fun print(){
            Log.d(TAG, "print:$name ")
        }
    }
}
  1. Kotlin中,将一个类定义在另一个类的内部,不加任何修饰符,则这个类将被默认为是一个嵌套类,如果加上inner修饰,则是一个内部类。

  2. Kotlin中的内部类可以访问外部类中的变量,而嵌套类却不可以访问。

枚举类

每个枚举常量都是一个对象,枚举常量用逗号分隔,枚举类的前面用enum关键字来修饰。

enum class Week{
    Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
}
密封类

这个暂时不太理解,略过。

数据类

Kotlin中的数据类型是专门用于存储数据的类 , 一般该类中不定义成员方法。

一般至于在class前添加data即可。

data class Person(val name: String, val age: Int)

Person 是一个数据类,它有两个属性 name 和 age。

比java中定义bean方便多了。

Kotlin 会自动为数据类生成以下方法:

  1. equals(other: Any?):用于比较两个对象是否相等。

  2. hashCode():用于生成对象的哈希码。

  3. toString():用于将对象转换为字符串的表示形式。

  4. copy():用于复制对象。

一般情况下 == 比较的是内容(也就是equals方法) , === 比较的是引用。

//true
(Person("谷歌", 100) == Person("谷歌",100))
//false
(Person("谷歌", 100) === Person("谷歌",100))
  1. 数据类的主构造函数至少有一个参数,如果需要一个无参的构造函数,可以将构造函数中的参数都设置为默认值。

  2. 数据类中的主构造函数中传递的参数必须用val或var来修饰。

  3. 数据类不可以用abstract、open、sealed或inner关键字来修饰。

  4. 在Kotlin 1.1版本之前数据类只能实现接口,1.1版本之后数据类可以继承其他类。

  5. 编译器可以自动生成一些常用方法,如equals()、hashCode()、toString()、componentN()、copy()等,这些方法也可以进行自定义。

单例模式

单例模式是通过object关键字来完成的,通过object修饰的类即为单例类,单例类在程序中有且仅有一个实例。

object Singleton {
    fun doSomething() {
        println("Doing something.")
    }
}
 
fun main() {
    Singleton.doSomething()
    // 确保返回相同的实例
    val another = Singleton
    // 输出: true
    println(another === Singleton) 
}
伴生类

由于在Kotlin中没有静态变量,因此它使用了伴生对象来替代Java中的静态变量的作用。伴生对象是在类加载时初始化,生命周期与该类的生命周期一致。

class BiuApp : Application() {
    companion object {
        final val TAG = "KApp_";
        lateinit var mContext: Context;
    }
    override fun onCreate() {
        super.onCreate()
        mContext = this;
        Log.d(TAG, "onCreate: ")
    }
}

//类似于static变量
BiuApp.TAG
BiuApp.mContext

由于伴生对象可以指定名称,也可以不指定名称,因此在调用伴生对象时分两种情况,具体如下。

(1)有名称:调用方式为“类名.伴生对象名.成员名”或“类名.成员名”。

(2)无名称:调用方式为“类名.Companion.成员名”或“类名.成员名”。

不过,我一般按照上面的,不写伴生类名。

对象

一切皆对象,对象就是一个真实世界中的实体。

对象是类的实例,具有独立的状态和行为。

对象的创建
var student1 = Student1();
var student2 = Student2("百度", 40);

委托

委托模式也叫代理模式,是最常用的一种设计模式。在委托模式中,如果有两个对象参与处理同一个请求,则接受请求的对象将请求委托给另一个对象来处理,简单来说就是A的工作交给B来做。委托模式是实现继承的一个很好的替代方式。在Kotlin中,委托是通过by关键字实现的,并且主要分为两种形式,一种是类委托,一种是属性委托。

委托类

委托是由两个对象完成的,一个是委托类,一个是被委托类。在委托类中并没有真正的功能方法,该类的功能是通过调用被委托类中的方法实现的。

interface IHousework{
    fun doHousework();
}
class Son:IHousework{
    override fun doHousework() {
        Log.d(TAG, "doHousework by Son: ")
    }
}
class Father : IHousework by Son(){
}

上面Father是委托类,没有任何代码,Son是被委托的类。

var father:Father = Father()
father.doHousework()

日志打印

doHousework by Son:

另外一种写法。

interface IHousework {
    fun doHousework();
}
class Son : IHousework {
    override fun doHousework() {
        Log.d(TAG, "doHousework by Son: ")
    }
}
class Father(iHousework: IHousework) : IHousework by iHousework {
}
var son = Son();
var father = Father(son)
father.doHousework()

打印结果跟上面一样。

延迟加载

在Kotlin中,声明变量或者属性的同时要对其进行初始化,否则就会报异常,尽管我们可以定义可空类型的变量,但有时却不想这样做,能不能在变量使用时再进行初始化呢?为此,Kotlin中提供了延迟加载(又称懒加载)功能,当变量被访问时才会被初始化,这样不仅可以提高程序效率,还可以让程序启动更快。

延迟加载是通过“by lazy”关键字标识的,延迟加载的变量要求声明为val,即不可变变量。

延迟加载也是委托的一种形式。

val lazyTxt: String by lazy {
    Log.i(TAG,"初始化lazyTxt")
    "lazy"
}
 
Log.d(TAG, " 1 : $lazyTxt")
Log.d(TAG, " 2 : $lazyTxt")

日志打印

初始化lazyTxt
1 : lazy
2 : lazy

只初始化了一次。

要求属性声明为val,即不可变变量,在java中相当于被final修饰。

参考文章

  1. 《Kotlin从基础到实战》

 历史上的今天

  1. 2023: Android Spinner介绍(0条评论)
  2. 2020: 查看目录下文件和文件夹个数以及文件夹目录结构(0条评论)
  3. 2019: 夏丏尊:幽默的叫卖声(0条评论)
版权声明 1、 本站名称: 91易搜
2、 本站网址: 91es.com3xcn.com
3、 本站内容: 部分来源于网络,仅供学习和参考,若侵权请留言
3、 本站申明: 个人流水账日记,内容并不保证有效

暂无评论

暂无评论...

随机推荐

朱自清:正义

正义是在我们心理!从明哲的教训和见闻的意义中,我们不是得着大批的正义么?但白白的搁在心里,谁也不去取用,却至少是可惜的事。两石白米搁在屋里,总要吃它干净,两箱衣服堆在屋里,总要轮流穿换,一大堆正义却扔在一旁,满不理会,我们真大方,真舍得!看来正义这东西也真*,竟抵不上白米的一个尖儿,衣服的一个扣儿。...

余秀华:我爱你

巴巴地活着,每天打水,煮饭,按时吃药阳光好的时候就把自己放进去,像放一块陈皮 茶叶轮换着喝:菊花,茉莉,玫瑰,柠檬这些美好的事物仿佛把我往春天的路上带 所以我一次次按住内心的雪它们过于洁白过于接近春天 在干净的院子里读你的诗歌。这人间情事恍惚如突然...

付志勇:为你写诗

为你写诗为你写下美丽的文字一个词就是一片绿叶一句话就是一萼花朵一首诗呢那里面呵一定有你想要的春天 你是我诗里婉约的女子是我千娇百媚的公主一袭紫衣花随衣襟从我门前的陌上悄悄走过你回眸浅浅一笑照亮尘世里我多少黯淡的时日 可我不是你想象里的王子真的不是...

Android Jetpack - Navigation的简单使用

前言Android Jetpack的Navigation确实好用,这里就简单记录一下,方便自己查阅。这个出来了很久了,但也就偶尔用用,用完就忘了,正应了微信之父张小龙的名言[用完即走]。PS: 好记性不如烂笔头。正文Jetpack的导航组件——Navigation,就可以很方便的管理各f...

贾平凹:喝酒

我在城里工作后,父亲便没有来过,他从学校退休在家,一直照管着我的小女儿。从来我的作品没有给他寄过,姨前年来,问我是不是写过一个中篇,说父亲听别人说过,曾去县上几个书店、邮局跑了半天去买,但没有买到。我听了很伤感,以后写了东西,就寄他一份,他每每又寄还给我,上边用笔批了密密麻麻的字。给我的信上说,他很...

Zygote的启动之一app_main

前言Android系统中,所有的应用程序以及SystemServer都是由Zygote进程孕育(fork)出来的。这里介绍app_main.cpp中的代码。Android P正文涉及文件\system\core\rootdir\init.rc\system\core\rootdir...