类是逻辑组织的基本单元,类含有以下成分:依赖包,类名,构造方法,属性,成员方法,伴生对象,接口,父类等

类的构造方法的完整逻辑过程

先考虑主构造函数,当主构造函数不够用时,再引入从构造函数。最初的主构造函数是这样的:步骤1通过主构造函数的参数传入数据,步骤2在类里定义所需的属性,步骤3在init代码块里对属性做初始化/赋值操作,这三个步骤分工明确,前后关联,共同完成了一个类的构造。

为了简化,Kotlin支持步骤2和步骤1合并操作,在主构造函数参数前加var/val;

支持步骤3和步骤2合并,对定义的属性直接赋值。支持步骤3和步骤2和步骤1合并操作,使用主构造函数的默认参数表达。

当然这些合并带来简便的同时,降低了构造的能力。

最初的状态(步骤1,步骤2,步骤3都存在)

class User(_sickName: String){val sickName: Stringinit {println("init")sickName = _sickName}
}

步骤3和步骤1合并的操作

open class User private constructor(val sickName: String = "Kotlin", var age: Int){init {println("init")}
}

步骤3,步骤2和步骤1的合并

class User(val sickName: String){init {println("init")}
}

**注意:**Java中需要重载构造方法的场景大多数都被Kotlin参数默认值和参数命名的语法特性涵盖了

子类的构造方法

“`
open class AirBook(name: String, val year: Int, val size: Int) {

constructor(name: String, year: Int) : this(name, year, 22){println("constructor")
}

}

class MacBookPro: AirBook{

public constructor(name: String, year: Int) : super(name, year) {
}public constructor(name: String, year: Int, size: Int) : super(name, year, size){
}

}

“`

子类在创建的时候,必须调用父类的构造函数,如果其父类还有父类,仍然要调用父类的父类的构造函数,直至顶层的基类。

open class AirBook(name: String, val year: Int, val size: Int){init {}constructor(name: String, year: Int) : this(name, year, 22){}
}

构造函数可以调用当前自身的构造函数,因为自身的构造函数必然有至少一个调用了父类的构造函数。

属性访问器

在kotlin里,一个属性 = 字段 + 属性访问器;这里的字段是Java里的成员变量

属性访问器分为读访问器getter,和写访问器setter

访问器里存在field字段,用来连接写访问器和读访问器,作为两者的通信桥梁

val修饰的属性只有读访问器,var修饰的属性既有有读也有写访问器

Kotlin引入属性访问器后,凡事对属性进行赋值操作,就会调用属性的写访问器setter;读取值的操作对应调用的是属性的读访问器

那么如果我们要自定义一个类似Java里的setter方法,要怎么做呢?

通过var变量的私有setter来实行

代码如下:

class TableLamp(val name: String, lightness: Int){var lightness: Int = 1private setfun setupLightness(lightness: Int){this.lightness = lightnessprintln("setupLightness lightness = $lightness")}
}

这样对属性lightness的修改,只能通过setupLightness方法。

修饰词final, open, abstract相互影响和使用

Kotlin的函数,类默认是final的,如果想重写函数,类有子类,则需使用open修饰。abstract修饰的函数和类,意味着有open的特性。这和Java的用法是一致的。

Kotlin自带的特殊类

数据类,嵌套类,内部类,密封类的基本写法这里就略去不谈。

数据类data

data修饰的类,必须有主构造函数,且主构造每个入参必须都val或var修饰

data修饰补充的方法里的所用的变量取决于主构造函数的入参

嵌套类和内部类

定义在某个类内部并用inner修饰的类称为内部类

嵌套类可以类比Java的静态内部类,Kotlin的内部类类比Java的内部类,他们含有外部类的引用。与Java内部类不同的是,Kotlin的内部类能对外部类的变量进行写操作。

举个例子

class TextView{var counter: Int= 0inner class Operator{fun calculate(){counter ++}}
}

内部类Operator的成员函数可以写外部类的counter属性,这在Java里是做不到的。

密封类

sealed关键词修饰的类,表达有限个子类。

sealed class Color constructor(val name: String)class Red : Color("Red")class Green : Color("Green")class Blue : Color("Blue")class Gray : Color("Gray")

上述写法,编译器就会知道,Color的子类的数量,此例Color一共只有四个子类,分别是:Red,Green, Blue, Gray。如果增加或删除Color的子类,编译器是能感知到的。密封类的子类可以作为嵌套类,也可以写在密封类所在的文件里,但是不能写在其他文件里。

举个和When搭配的应用例子:

fun testSealed(color: Color): Int =when (color) {is Red -> {println("Red")1}is Green -> {println("Green")2}is Blue -> {println("Blue")3}is GRAY ->{println("GRAY")4}}

密封类的意义:
如果不用密封类,使用when总是不得不添加一个默认分支。更重要的是,如果你添加了一个新的子类,编译器并不能发现有地方改变了。如果你忘记了添加一个分支,就会选择默认的选项,这可能导致潜在的bug。

使用密封类就能解决上述的问题。

Object的使用

声明一个类并创建一个对应的实例。与类一样,对象可以包含属性,方法,初始化语句块等的声明。对象声明可以继承类和实现接口,尤其不包含状态的时候很适用,也可以有扩展函数。

对象声明

创建单一的实例,对象声明在定义的时候就创建了,不需要在代码的其他地方调用构造方法。

因此,对象声明不允许有构造函数。

object CaseInsensitiveFileComparator : Comparator<String>{override fun compare(o1: String, o2: String): Int {return o1.compareTo(o2, true)}
}

Java调用上述代码,则需要通过INSTANCE来调用,如下

 CaseInsensitiveFileComparator.INSTANCE.compare("abc", "abe");

伴生对象

创建单一的实例,可以实现Java里访问类的私有成员的静态方法

在对象声明的基础上,使用companion关键字来标记,这样做就获得了直接通过容器类名称来访问这个对象的方法和属性的能力。

举个例子,实现CarFactory工厂

通过对象声明的实现

class CarFactory{object Instance{fun newCar(name: String): Car{return Car(name)}fun newRedCar(name: String): Car{return Car(name, Red())}}
}

调用

  CarFactory.Instance.newCar("Mini Cooper")

通过伴生对象的实现

class CarFactory{companion object {fun newCar(name: String): Car{return Car(name)}fun newRedCar(name: String): Car{return Car(name, Red())}}
}

调用

CarFactory.newCar("Mini Cooper")

对象表达式

既然是表达式,就意味着有返回值

与Java的匿名内部类只能扩展一个类或者实现一个接口不同,Kotlin的匿名对象可以实现多个接口或者不实现接口。

与对象声明不通,匿名对象不是单例的。每次对象表达式被执行都会创建一个新的对象实例。在对象表达式里不经可以访问创建它的函数中的变量,还可以修改变量的值

举个例子

fun countClick(view: View){var clickCount = 0view.addClick(object : IClick{override fun onClick() {clickCount ++ }})
}

小结

object对象在Kotlin中的意义:

  1. 实现Java里静态的功能,等效实现静态调用
  2. 代替Java匿名内部类书写

接口

interface IFocus {val focusName: Stringfun showOff(){println("IFocus foucusName length = ${focusName.length}")}fun onFocus()
}

IFocus接口声明函数,让子类实现,默认方法showOff,和抽象方法onFucus

class View : IFocus{override val focusName: Stringget() = "View"override fun onFocus() {showOff()}
}

View实现IFocus接口,focusName由View来确定,获取focusName逻辑写在IFocus的默认方法里。调用如下

val view = View()
view.onFocus()

调用返回内容

IFocus foucusName length = 4

其他

访问权限修饰词

protected在Kotlin和Java的区别
kotlin中protected只能是其子类和自身才能访问;Java中则是同包下所有文件和不同包的子类能访问

Kotiln访问权限由小到大排列依次是:
private, protected, internal, public

Kotlin函数和属性默认是public的,Java的默认是包级访问范围,即同一个包下的类能访问。
Kotlin缺少包级别访问控制,而多了一个模块访问范围internal。internal表示同一个项目模块下的类都能访问

参考资料

Kotlin实战

【基础篇】Kotlin第四讲-类、对象和接口相关推荐

  1. python 字符串替换_Python基础教程,第四讲,字符串详解

    本节课主要和大家一起学习一下Python中的字符串操作,对字符串的操作在开发工作中的使用频率比较高,所以单独作为一课来讲. 学完此次课程,我能做什么? 学完本次课程后,我们将学会如何创建字符串,以及如 ...

  2. 判断字符串格式_Python基础教程,第四讲,字符串详解

    本节课主要和大家一起学习一下Python中的字符串操作,对字符串的操作在开发工作中的使用频率比较高,所以单独作为一课来讲. 学完此次课程,我能做什么? 学完本次课程后,我们将学会如何创建字符串,以及如 ...

  3. 鸟哥的Linux私房菜-基础篇第四版.pdf免费资源下载链接,《鸟哥的Linux私房菜-基础篇》第四版.pdf

    <鸟哥的Linux私房菜-基础篇>第四版.pdf免费资源下载链接(.pdf书籍的优点是便于直接在电脑中保存有电脑就可以阅读,如果觉得这本书给你提供到了很大的帮助,可以去书店补一本纸质版) ...

  4. 《鸟哥的Linux私房菜-基础篇》第四版 简体中文 PDF 带完整书签

    <鸟哥的Linux私房菜-基础篇>第四版 简体中文 PDF 带完整书签 共二十四章 下载地址:https://download.csdn.net/download/csdn12345678 ...

  5. 鸟哥的Linux私房菜(基础篇)- 第二十四章、 X Window 配置介绍

    第二十四章. X Window 配置介绍 最近升级日期:2009/08/07 在 Linux 上头的图形介面我们称之为 X Window System,简称为 X 或 X11 罗!为何称之为系统呢?这 ...

  6. 疯狂的大柚柚带你玩转MSP-ESP430G2(基础篇)----(十四)中断系统

    疯狂的大柚柚带你玩转MSP-ESP430G2(基础篇) (十三)中断系统 中断是暂停CPU正在运行的程序,转去执行相应的中断服务程序,完毕后返回被中断的程序继续运行的现象和技术. 中断源(中断分类) ...

  7. 鸟哥的Linux私房菜(基础篇)- 第十四章、Linux 账号管理与 ACL 权限配置

    第十四章.Linux账号管理与 ACL 权限配置 最近升级日期:2009/09/09 要登陆 Linux 系统一定要有账号与口令才行,否则怎么登陆,您说是吧?不过,不同的使用者应该要拥有不同的权限才行 ...

  8. Java基础篇:一个简单的类

    让我们先从一个简单的例子来开始对类的研究.下面定义了一个名为box的类,它定义了3个实例变量:width,height和depth.当前,box类不包含任何方法(但是随后将增加一些). class B ...

  9. 《鸟哥的私房菜基础篇》第四版学习笔记——第1章Linux是什么与如何学习

    文章目录 一.Liux是什么?? 1.是操作系统or应用程序?? 2.Linux之前,Unix的历史 3.关于 GNU 计划.自由软件与开放原始码 二.Torvalds 的 Linux 发展 1.与 ...

最新文章

  1. 基于图像的三维模型重建——相机模型与对极几何
  2. php yaf框架模块化,基于yaf的模块化开发方案
  3. 计算机网络与影视多媒体技术 南京理工大学,计算机网络多媒体数学库和课件结构设计-计算机仿真论文-计算机论文(8页)-原创力文档...
  4. pacf和acf_如何通过Wordpress API,ACF和Express.js使Wordpress更加令人兴奋
  5. 给窗口设置系统级或窗口级的热键
  6. 重温数据结构:树 及 Java 实现(转)
  7. C++ 封装DLL遇到的一些坑爹问题与解决方案
  8. javascript 忽略 报错_.babelrc ignore忽略js无效
  9. Csharp: create Transparent Images in winform
  10. 【7.1】property动态属性
  11. 三维重建笔记_多视几何_求基本矩阵F_六/七/八点法_误差评估
  12. 【1】嵌入式TCP/IP协议——————Art-Net调试工具 DMX-Workshop
  13. 【python包】NumPy-快速处理数据2
  14. 为什么要用promise处理ajax,为什么要使用promise
  15. iPhone6和iPhone6Plus的适配
  16. 深圳招银java社招都有hr面吗,深圳招银网络科技
  17. 小偷和抢劫是被怎么遏制的?
  18. 汽车功能安全工程师必看!ISO 26262认证基本原理解析
  19. 龙博方案网Big Faceless Java图形展现控件详细介绍及下载
  20. python爬iptv直播源脚本_GitHub - Good0007/iptv-m3u-maker: IPTV 国内+国外 电视台直播源m3u文件, 收集汇总本地源脚本...

热门文章

  1. np.random.randint函数
  2. 2022年博客新星排行榜 日榜 2023-01-02 博客新星榜
  3. 微信小程序做页内跳转外部网络连接/<web-view>的使用(使用与企业小程序)
  4. jmeter 登录(录制 )
  5. Linux 安装宝塔面板
  6. 《计算机导论》专业课程的知识总结,计算机导论知识点
  7. VS调试器开机提示“HPLaserJetService.exe“发生未经处理的异常-解决方案
  8. ios 主题切换 思路_iOS主题皮肤切换
  9. NGS数据分析实践:05. 测序数据的基本质控 [1] - FastQC
  10. 面试不行,是你的逻辑问题--如何提升逻辑表达能力,让说话随时都能条理清晰?