About Kotlin-Kotlin中的类1

About Kotlin(1)

因为是从Java的角度来学习Kotlin,在Java中,类作为第一等公民。故学习Kotlin,也先从其的类开始。

Kotlin中的类

参考文章

  1. https://hltj.gitbooks.io/kotlin-reference-chinese/content/txt/object-declarations
  2. http://blog.csdn.net/zxc123e/article/details/73618709
  3. http://blog.csdn.net/zxc123e/article/details/73650039

普通的类 class

Kotlin中没有添加修饰符直接以class开头的都是final类。final类的意义在于JVM可能存在的优化(常量和方法内联)和防止继承的滥用。

《Effective Java》在第17条说,要么为继承而设计,并提供文档说明,要么就禁止继承。

构造方法

Kotlin中一个类有一个primary的构造方法和可以多个的secondary的构造方法。

//如果一个类,没有类体,甚至连花括号都可以省略
class Empty
//如果主构造方法没有注解/修饰符。则constructor可以直接省略
class Person constructor(firstName:String){}
//省略的写法
class Person(firstName:String){}
//注解
class Person @Inject constructor(firstName:String){}
//修饰符
class Person private constructor(firstName:String){}
//第二构造器
class Person(val name:String){
  //可以只用this,来指代第一个构造器
    constructor(name:String,parent:Person):this(name){
      //方法中,this同样可以用来指代对象
        parent.childeren.add(this)
    }
}
初始化
//如果使用默认构造方法的话,初始化代码不能现在方法内
class Customer(name:String){
  //使用init代码块来完成主构造函数的中的初始化
    init{
        logger.info("Custormer initialized with value ${name}")
    }
}
//另外,主构造函数传入的值,可以直接在类的变量中使用
class Customer(name:String){
  //属性变量可以直接使用构造函数中的变量
    val cumtomerKey = name.toUpperCase()
}
//通过这样,可以将主要构造方法中的参数直接变成类的属性.还可以直接写默认值
//在JVM上面会自动生成无参构造方法
class Customer(val firstName:String="",var lastName:String,var age:Int){
    
}

Kotlin中可以提供默认值的方式,解放了手写的代码量,及构造器模式Builder Pattern!

Effective Java的条目2讲述了如何有效地使用构造器模式(Builder Pattern)当Java构造函数有很多可选参数时,代码将变得冗长,可读性差且容易出错。构建这样的对象需要写很多代码。

对应的Open类

对应上面的类,kotlin中的open类就是能够被继承的了。必须在类声明的时候使用open关键字。Kotlin社区有人对这个 “默认的final” 设计很不满。Kotlin论坛对此进行了激烈的讨论。后来,在Kotlin 1.1 beta版中提供了一个编译器插件,可以让class默认是open。

//Kotlin中所有类的父类是Any,类似于Object,不过Any不输于java.lang.Object,其有三个方法
//这里的operator是操作符重载,在Kotlin中的符号中会说明
public open operator fun equals(other:Any?):Boolean
public open fun hashCode():Int
public open fun toString():String

覆盖方法

override的强制使用。

Java 1.5 中加入了注解(annotation),其中最重要的一个是重写(override),表示这个方法是对超类中该方法的重写。基于书中条目36,应该尽量使用这个可选注解以避免一些恶心的bug。比如当你以为你重写了超类的方法但其实并没有时,编译器会抛出一个错误。不过如果你记得加上了override注解的话就没事。

在Kotlin中,override不是可选的注解而是强制关键字。所以由此引发的bug就不会再有了,编译器会提前警告你。Kotlin把这些事清楚的展现出来。

open class Base{
    open fun v(){}
  fun nv(){}
}
class Derived():Base(){
  //override 关键词的使用
    override fun v(){}
}

//如果使用相同的两个方法。则可以用super类指代不同的父类的方法
interface B{
    fun v(){print("B")} //interface也能够写方法的实现
}
class DoubleImpl():Base(),B{
    override fun v(){
        //调用 Base.v()
      super<Base>.v()
      //调用B的方法的话
      super<B>.v()
    }
}

//这里还有个需要注意的是,属性的重写也需要用override
open class Foo{
    open val x:Int get{...}
}
class Bar1:Foo(){
    override val x:Int=...
}

数据类

所谓的数据类,就是Java的Pojo,除了字段外,基本不会写其他的方法。

//在Kotlin中,可以使用data关键字
data class User(val name:String,val age:Int)
自动生成的函数

编译器会自动的从主构造函数中根据所有声明的属性提取以下函数

  • equals()/hashCode()

  • toString

  • componentN() functions 对应属性。按照顺序排列

  • copy 函数。

    //关于深拷贝的例子。有时候只是需要修改部分的属性
    val java = User(name="Jack",age=1)
    val oderJack = java.copy(age=2)
    //对于上面User类。copy的实现就如下
    fun copy(name:String=this.name,age:Int=this.age)=User(name,age)
    
确保有意义

为了确保数据类是一致的并且有意义的。该类必须有至少一个参数,不能其他的类型。

如果生成的类需要无参构造函数,则所有的属性必须指定默认值

解构声明赋值

注意,这个解构声明是专属于data class的

data class Person(var name:String="lisi",var age= 12)
val person = Person("kobe",30)
//将对象解构
val (name,age)=person
//内部实现为
val name = person.component1()
val age = person.component2()

var (name,_)=Person()   //不需要使用变量时,可以用下划线替代

下面这个是一个更直接的例子

//因为有了ComponentN方法,才可以使用解构函数
class Pair<K,V>(val first:K,val second:V){
    operator fun component1():K{
        return first
    }
  
  operator fun component2():V{
      return second
  }
}
//vararg 是可变参数的意思
fun main(vararg args:String){
    val pair = Pair(first=1,second="One")
  val (num,name)=pair
  println("num=$num,name=$name")
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,539评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,594评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,871评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,963评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,984评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,763评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,468评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,850评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,002评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,144评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,823评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,483评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,026评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,150评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,415评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,092评论 2 355

推荐阅读更多精彩内容