Kotlin 中的操作符重载汇总表 与 可见性修饰符总结

本篇的知识点会在《 3.2.2 在 Kotlin 中实现 RecyclerView 及其点击事件》中被用到,到时可以回头进行查阅。

一、操作符重载

就像其他每种语言一样,Kotin有一些固定数量象征性的操作符,这里预定义了一些操作符执行一定的操作,我们可以在任何类中很容易地使用它们。比如典型的加(+),减(-),乘(*),除(/),而且还有很多其它的。

类似Java这样的一些语言,这些操作符被限制在一些特定的数量类型上,且没有方法让其他类型数据使用这些操作符。不过Kotlin有这种方案:它有一些预定义的操作符,但是我们能够为任意数据类型而重载它们。方法也很简单,那就是创建一个函数,函数名为保留的操作符关键字,这样就可以让这个操作符的行为映射到这个函数,重载这些操作符可以增加代码可读性和简洁性。

1、操作符表

这里你可以看见一系列包括操作符和对应方法的表,对应方法必须在指定的类中通过各种可能性被实现:

一元操作符
操作符函数
+aa.unaryPlus()
-aa.unaryMinus()
!aa.not()
a++a.inc()
a–a.dec()
二元操作符
操作符函数
a + ba.plus(b)
a - ba.minus(b)
a * ba.times(b)
a / ba.div(b)
a % ba.mod(b)
a..ba.rangeTo(b)
a in ba.contains(b)
a !in b!a.contains(b)
a += ba.plusAssign(b)
a -= ba.minusAssign(b)
a *= ba.timesAssign(b)
a /= ba.divAssign(b)
a %= ba.modAssign(b)
数组操作符
操作符函数
a[i]a.get(i)
a[i, j]a.get(i, j)
a[i_1, …, i_n]a.get(i_1, …, i_n)
a[i] = ba.set(i, b)
a[i, j] = ba.set(i, j, b)
a[i_1, …, i_n] = ba.set(i_1, …, i_n, b)
等于操作符
操作符函数
a == ba?.equals(b) ?: b === null
a != b!(a?.equals(b) ?: b === null)

相等操作符有一点不同,为了达到正确合适的相等检查做了更复杂的转换,因为要得到一个确切的函数结构比较,不仅仅是指定的名称,方法必须要如下准确地被实现:

operator fun equals(other: Any?): Boolean

操作符===和!==用来做身份检查(它们分别是Java中的==和!=),并且它们不能被重载。

激活(invoking)函数调用
方法调用
a(i)a.invoke(i)
a(i, j)a.invoke(i, j)
a(i_1, …, i_n)a.invoke(i_1, …, i_n)

二、操作符重载的例子

1、onBindViewHolder中的使用

你可以想象,Kotlin List是实现了数组操作符的,所以我们可以像Java中的数组一样访问List的每一项。除此之外:在可修改的List中,每一项也可以用一个简单的方式被直接设置:

val x = myList[2]
myList[2] = 4

我们这里给出一个叫TestList的数据类,它是由很多其他额外的信息组成的,有趣的是我们可以直接访问它的每一项而不是请求内部的list得到某一项。做一个完全不相关的事情,我要去实现一个size()方法,它能稍微能简化一点当前的Adapter:

data class TestList(val city: String, val country: String, val dailyTest: List<Test>) {
    operator fun get(position: Int): Test = dailyTest[position]
    fun size(): Int = dailyTest.size
}

这样会使我们的onBindViewHolder更简单一点(后面的文章《 3.2.2 在 Kotlin 中实现 RecyclerView 及其点击事件》会继续讲解相关内容):

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    with(weekTest[position]) {
        holder.textView.text = "$date - $description - $high/$low"
    }
}

当然还有getItemCount()方法:

override fun getItemCount(): Int = weekTest.size()
2、扩展函数中的操作符

我们不需要去扩展我们自己的类,但是我需要去使用扩展函数扩展我们已经存在的类来让第三方的库能提供更多的操作。几个例子,我们可以去像访问List的方式去访问ViewGroup的view:

operator fun ViewGroup.get(position: Int): View = getChildAt(position)

现在真的可以非常简单地从一个ViewGroup中通过position得到一个view:

val container: ViewGroup = find(R.id.container)
val view = container[2]

如果你暂时看不懂其实没关系,这里我们所说的会在之后的章节中全部讲解到,点击关注即可。

三、可见性修饰符

和Java中的一样,Kotlin中的类、对象、接口、构造函数、属性以及它们的 setter 方法都可以有可见性修饰词,并且也是类似的四个:private、protected、internal 以及 public。但是Kotlin中这些修饰符是与我们Java中的使用是有些不同的,比如在这个语言中默认的修饰符是public,这就节约了我们很多的时间、字符和绳命,下面我们来详细看一下。

1、修饰符

(1)private

private 修饰符是我们使用的最具有限制性的修饰符,它表示它只能被自己所在的文件可见。所以如果我们给一个类声明为private,我们就不能在定义这个类之外的文件中使用它。

另一方面,如果我们在一个类里面使用了private修饰符,那访问权限就被限制在这个类里面了,甚至是继承这个类的子类也都不能使用它。所以类、对象、接口……(也就是包成员)如果被定义为private,那么它们只会对被定义所在的文件可见,如果被定义在了类或者接口中,那它们只对这个类或者接口可见。

(2)protected

这个修饰符的存在就是只能修饰类或者接口中的成员上,一个包成员不能被定义为protected,包级属性是不能修饰的。而定义在一个成员中,就与Java中的方式一样了:它可以被成员自己和继承它的成员可见,比如类和它的子类。

(3)internal

在Kotlin中就因为有了包级的属性(而java包下面只能是类或者接口等,所以Kotlin就可以很随意的去定义变量、类、接口、函数等),所以才多了个internal修饰符。而为了区别于protected,被internal修饰的类、函数或者接口可以在同一module下访问,除此之外如果internal修饰的是类内部的成员,那这个成员就成了只有这个类内部能访问的成员,比如private修饰的类,就只能在类的内部访问。

也就是说,如果是一个定义为internal的包成员的话,对所在的整个module可见。如果它是一个其它领域的成员,它就需要依赖那个领域的可见性了。比如,如果我们写了一个private类,那么它的internal修饰的函数的可见性就会限制与它所在的这个类的可见性。总之,我们可以访问同一个module中的internal修饰的类,但是不能访问其它module的。

什么是module?

根据Jetbrains的定义,一个module应该是一个单独的功能性的单位,它应该是可以被单独编译、运行、测试、debug的。根据我们项目不同的模块,可以在Android Studio中创建不同的module。在Eclipse中,这些module可以认为是在一个workspace中的不同的project。

(4)public

你应该可以猜想到,这是最没有限制的修饰符。而且这个修饰符与java最大的不同是,它在Kotlin中是默认的,也就是我们不声明的属性会默认成为public。当然了它只限制于它的领域,一个定义为public的成员被包含在一个private修饰的类中,这个成员在这个类以外也是不可见的。

2、构造器与代码润色

所有构造函数默认都是public的,它们类是可见的,可以被其它地方使用,不过我们也可以使用这个语法来把构造函数修改为private:

class C private constructor(a: Int) { ... }

如果我们在编写类的时候,你觉得某些属性因为是什么原因不能对别人可见,那就把它定义为private:

class RequestForecastCommand(private val zipCode: String)

上面这段代码所作的事情就是创建了一个不可修改的属性zipCode,它的值我们只能去得到,不能去修改它,所以这个不大的改动让代码看起来更加清晰。

而且在Kotlin中,我们不需要去指定一个函数的返回值类型,它可以让编译器推断出来。举个省略返回值类型的例子:

data class TestList(...) {
    fun get(position: Int) = dailyTest[position]
    fun size() = dailyTest.size()
}

我们可以省略返回值类型的典型情景是:当我们要给一个函数或者一个属性赋值,而又不需要去写代码块去实现的时候。

联系方式:

简书:WillFlow
CSDN:WillFlow
微信公众号:WillFlow

微信公众号:WillFlow

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PostgreSQL是以加州大学伯克利分校计算机系开发的POSTGRES,现在已经更名为PostgreSQL. PostgreSQL支持大部分SQL标准并且提供了许多其它现代特:复杂查询、外键、触发器、视图、事务完整等。 PostgreSQL 是一个免费的对象-关系数据库服务器(数据库管理系统),它在灵活的 BSD-风格许可证下发行。它提供了相对其他开放源代码数据库系统(比如 MySQL 和 Firebird),和专有系统(比如 Oracle、Sybase、IBM 的 DB2 和 Microsoft SQL Server)之外的另一种选择。 事实上, PostgreSQL 的特覆盖了 SQL-2/SQL-92 和 SQL-3/SQL-99,首先,它包括了可以说是目前世界上最丰富的数据类型的支持,其有些数据类型可以说连商业数据库都不具备, 比如 IP 类型和几何类型等;其次,PostgreSQL 是全功能的自由软件数据库,很长时间以来,PostgreSQL 是唯一支持事务、子查询、多版本并行控制系统(MVCC)、数据完整检查等特的唯一的一种自由软件的数据库管理系统。 Inprise 的 InterBase 以及SAP等厂商将其原先专有软件开放为自由软件之后才打破了这个唯一。最后,PostgreSQL拥有一支非常活跃的开发队伍,而且在许多黑客的努力下,PostgreSQL 的质量日益提高。从技术角度来讲,PostgreSQL 采用的是比较经典的C/S(client/server)结构,也就是一个客户端对应一个服务器端守护进程的模式,这个守护进程分析客户端来的查询请求,生成规划树,进行数据检索并最终把结果格式化输出后返回给客户端。为了便于客户端的程序的编写,由数据库服务器提供了统一的客户端 C 接口。而不同的客户端接口都是源自这个 C 接口,比如ODBC,JDBC,Python,Perl,Tcl,C/C++,ESQL等, 同时也要指出的是,PostgreSQL 对接口的支持也是非常丰富的,几乎支持所有类型的数据库客户端接口。这一点也可以说是 PostgreSQL 一大优点。 本课程作为PostgreSQL数据库管理二,主要讲解以下内容:1.     PostgreSQL的子查询2.     PostgreSQL公共表表达式3.     PostgreSQL数据的修改4.     PostgreSQL的事务5.     PostgreSQL数据导入和导出6.     PostgreSQL数据库的管理7.     PostgreSQL表的管理

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值