4、Kotlin基础---类和对象

1、类定义
Kotlin类可以包含:构造函数和初始化代码块、函数、属性、内部类、对象声明。
创建类:

class Runoob{       //创建名为Runoob的类
}

定义空类:

class Empty

含有成员函数的类:

fun main(args: Array<String>) {
    var s = Student()
    s.introduce()
}

class Student{
    fun introduce(){ println("I am a student") }
}

类的属性
类的属性可以用关键字var声明为可变的,否则使用只读关键字val声明为不可变。

例子:
class Student{
  var name:String = ...
  var address:String  =... 
  var phone:String  =...
}

kotlin中创建对象没有了new关键字,我们可以像调用普通函数一样调用类的构造方法;
例如:

val student = Student()

想要使用类中的属性,只要用名称引用它即可
例如:

student.name

getter和setter
属性声明的完整语法:

var <propertyName>[:<PropertyType>][=<property_initializer>]
[<getter>]
[<setter>]

如果属性类型可以从初始化语句中推断出来,那么类型就可以省略;
在kotlin中,声明一个类的成员变量时,默认实现了getter和setter方法;
用val修饰的属性不允许设置setter函数,因为它本身就是只读的;

例如:
var allByDefault:Int?   //错误:需要一个初始化语句
var initialized = 1     //类型为Int,默认实现了getter和setter
val simple:Int?     //类型为Int,默认实现了getter,但必须在构造函数中初始化
val inferredType = 1    //类型为Int,默认实现了getter

在kotlin的getter方法中不能使用当前属性的引用,set方法中不能对当前属性进行赋值;

例如:
var no:Int = 100
get() = no      //这里如果使用当前属性的引用,会递归调用属性的get方法
set(value){
no = value  //同理,如果在这给no赋值,会递归调用属性的set方法
}

为了防止这种情况的发生,kotlin引入了后端变量的概念,后端变量使用field表示;

例如:
class Student{
    var number:Int = 1001
    get() = getDate()+field
    set(value){
        field = getDate()+value
    }

    fun introduce(){ println("I am a student") }
     //获取年份
    private fun getDate():Int{
         var date = Calendar.getInstance().get(Calendar.YEAR)
         return date*10000
    }
}

非空属性必须在定义的时候初始化,kotlin提供了一种可延迟初始化的方案,使用lateinit关键字描述属性:

public class MyTest{
  lateinit var subject:TestSubject

  fun setup(){
      subject = TestSubject()
  }
}

主构造器
主构造器不能包含任何代码,初始化代码可以放在初始化代码段中,初始化代码段使用init关键字作为前缀。

class Person constructor(firstName :String){
  init{
    println("FirstName is $firstName")
  }
}

当然在这里主构造器的参数可在初始化的代码片段中使用,也可以在属性初始化的代码中使用;另
外一种简单的写法就是用主构造器来定义属性并初始化属性值。例如:

class Person(val firstName:String,val lastName:String){
    //....
}

如果构造器有注解,或者有可见度修饰符,这时constructor关键字是必须的,注解和修饰符要放在它之前。

次构造函数
类也可以有二级构造函数,需要添加前缀 constructor

class Person{
  constructor(parent:Person){
    parent.children.add(this)
  }
}

如果类有主构造函数,每个次构造函数都要,直接或间接通过另一个次构造函数代理主构造函数。在同一个类中代理另一个构造函数使用关键字this关键字:

class Person(val name:String){
  constructor(name:String,age:Int):this(name){
      //初始化...
  }
}

如果一个非抽象类没有声明构造函数(主构造函数或次构造函数),它会会产生一个没有参数的构造
函数,构造函数时public的,如果你不想你的类有公有的构造函数,你需要声明一个空的主构造函
数:

 class Single private constructor(){}

实例练习:
class WebSite constructor(name:String){
    var url:String ="http://www.baidu.com"
    var country:String = "CN"
    var siteName = name

    init{
        println("初始化网站名:$name")
    }

    constructor(name:String,alexa:Int):this(name){
        println("Alexa 排名 $alexa")
    }

}

2、抽象类
抽象类和java一样使用abstract修饰,同样使用abstract修饰的成员方法不存在具体实现。
注意:无需对抽象类或抽象成员标注open注解。

open class Base {
    open fun f(){}
}

abstract class Dervied:Base(){
    abstract override fun f()
}

嵌套类
kotlin中可以嵌套的声明类,这里和java内部类不同,其他类要使用嵌套类时,只需要外部类的
类名引用来创建嵌套类的对象,如下:

class Outer{        //外部类
    private val bar:Int = 1
    class Nested{       //嵌套类
        var ot:Outer = Outer()
       fun foo() {
            println(out.bar)  //嵌套类想要引用外部类的变量,需要先创建外类的对象
        }
    }
}

fun main(args:Array<String>){
    val demo = Outer.Nested().foo()
    println(demo)
}

内部类
内部类使用inner关键字来表示。
内部类会带有一个对外部类的对象的引用,所以内部类可以访问外部类成员属性和成员函数。

class Outer{
    private val bar:Int=1
    var v = "成员属性"
    inner class Inner{
        fun foo() = bar
        fun innerTest(){
            var o = this@Outer
            println("内部类可以引用外部类的成员,例如:"+o.v)
        }
  }
}

fun main(args: Array<String>) {
    val demo = Outer().Inner().foo()
    println(demo)
    val demo2 = Outer().Inner().innerTest()
    println(demo2)
}

匿名内部类
class Demo{
    fun setInterface(test:TestInterface){
        test.test()
    }
}

interface TestInterface{
    fun test()
}

fun main(args: Array<String>) {
    var demo = Demo()
    demo.setInterface(object :TestInterface{
        override fun test() {
            println("匿名内部类的方法,哈哈哈")
        }
    })
}

这里匿名内部类和java中的有区别,object:TestInterFace中的object是kotlin的关键字;

类的修饰符总结
和java一样,类的修饰符分为两种classModifier和accessModifier:

classModifier:类属性修饰符,用来标识类本身特性。
abstract        //抽象类
final           //类不可继承,默认属性
enum        //枚举类
open        //可继承类,类默认是final的
annotation  //注解类

accessModifier:访问权限修饰符

private //仅在同一个文件中可见
protected //同一个文件中或子类中可见
public //所有调用的地方都可见
internal //同一个模块中可见

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,056评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,842评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,938评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,296评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,292评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,413评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,824评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,493评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,686评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,502评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,553评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,281评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,820评论 3 305
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,873评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,109评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,699评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,257评论 2 341

推荐阅读更多精彩内容

  • 写在开头:本人打算开始写一个Kotlin系列的教程,一是使自己记忆和理解的更加深刻,二是可以分享给同样想学习Kot...
    胡奚冰阅读 1,411评论 5 11
  • Kotlin的类和接口与Java的类和接口是有一定的区别的。Kotlin的接口是可以包含属性声明。Kotlin默认...
    程自舟阅读 10,309评论 0 11
  • 面向对象编程(OOP) 在前面的章节中,我们学习了Kotlin的语言基础知识、类型系统、集合类以及泛型相关的知识。...
    Tenderness4阅读 4,414评论 1 6
  • 如果描述的类型不是基本类型怎么办? 任何复杂的数据类型都是由基本的数据类型构成的 面向对象 使用基本数据类型描述复...
    JunChow520阅读 2,196评论 0 1
  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,727评论 2 9