zoukankan      html  css  js  c++  java
  • Kotlin学习-类(嵌套类,内部类,数据类,静态类)及类扩展

    一般类形式:

    class Person(var name: String){//构造函数放在类头部
        var age = 1
        var fulName: String
        var address = "china"
    
        init {//初始化模块,与第一构造函数同时执行
            fulName = name+"_haha"
        }
    
        //类内部成员变量访问通过get,set方法访问
        //备用字段使用field声明,field只能用于属性的访问器
        var lastName: String = "zhang"
            get() = field.toUpperCase()
            set//禁止修改
    
        //二级构造函数,需要加前缀 constructor:
        constructor (name: String, age:Int) : this(name) {
            //this.fulName = name
            this.age = age
        }
    
        var no: Int = 100
            get() = field  // 备用字段表示当前属性,对当前字段值只能通过此field处理
            set(value) {  //变量修改方式
                if (value < 10) {
                    field = value
                } else {
                    field = -1
                }
            }
    
        var heiht: Float = 145.4f
            private set
    
        private fun selfMethod(){//私有方法
            println("self method ")
        }
    
        fun sayHello(){//无修饰符,默认public
            print("hello! nice to meet you!")
        }
    
        private val bar: Int = 1
        inner class MyInner{//内部类 in
            fun ff() = bar  // 访问外部类成员
            fun innerTest() {
                var o = this@Person //获取外部类的成员变量
                //内部类引用外部类成员
                println("name=${o.name}, age=${o.age}")
            }
        }
    
         class Nested {// 嵌套类
            fun foo() = "nest class content"
             fun myHandle(){
                println("Nested instance method invoke!")
             }
        }
    
    }
    

     类访问
     val p = Person("haha")
     p.address = "beijing"//set

    嵌套类访问
    var pnest = Person.Nested()
    pnest.foo()
    内部类访问
    var pinner = Person("Tom").MyInner()// 内部类,Outter后边有括号
    pinner.innerTest()

    匿名内部类:

    kotlin object 对象表达式,相当于java匿名类

     fab.setOnTouchListener(object :View.OnTouchListener{//匿名类实现监听器
            override fun onTouch(v: View?, event: MotionEvent?): Boolean {
                return false
            }
        })
    //简化为lambda表达式形式
    fab2.setOnTouchListener { v , event ->
                if(event.action == MotionEvent.ACTION_UP){
                    var pnest = Person.Nested()
                    var str = pnest.foo()
                    tvContent?.text = str
                }
                false
     }

    静态类,kotlin没有静态类,静态方法,可以使用object修饰符替代 Java static功能

    object SampleClass{
        var name: String = "jack tom"
        var no: Int = 101
        fun bar() {}
    }
    

     访问方式,

     SampleClass.name
     SampleClass.bar()

    class SingletonSample2 private constructor() {
    // 一个类里面只能声明一个内部关联对象,即关键字 companion 只能使用一次
        companion object {//通过companion object实现单例模式
            val instance = SingletonHolder.holder
    		val tt:String = "static object"
        }
    
        private object SingletonHolder {
            val holder = SingletonSample2()
        }
    
        fun hello(){}
    	
    }
    

    工厂模式实现:

    interface Factory<T> {
        fun create(): T
    }
    
    class MyClass private constructor(){
        companion object : Factory<MyClass> {
            override fun create(): MyClass = MyClass()
        }
    }
    

    类属性延迟初始化:

    kotlin为确保类型安全,属性在声明和定义时需要指定属性值,但对于想要延迟初始化或者开始无法确定时我们需要特殊处理,实现方式 lateinit关键字,layzy函数

    class User(var name:String){
    	//延迟初始化方式一
        lateinit var play:String //lateinit表示延迟初始化,若没有初始化使用则抛出异常
    
        fun setUpValues(){
            play = "basketball"//String("football")
        }
    
        //延迟初始化方式二
        //lazy() 是一个函数, 接受一个 Lambda 表达式作为参数, 返回一个 Lazy <T> 实例的函数,
        // 返回的实例可以作为实现延迟属性的委托
        val lazyValue: String by lazy {
            println("computed!")     // 第一次调用输出,第二次调用不执行
            "Hello world"
        }
    //   println(lazyValue)   // 第一次执行,执行lazy函数
    //   println(lazyValue)   // 第二次执行,只输出返回值 hello
    
        //延迟初始化方式三,Delegates属性代理方式实现
        //notNull 适用于那些无法在初始化阶段就确定属性值的场合
        var notNullBar: String by Delegates.notNull<String>()
        //foo.notNullBar = "bar"
        //如果属性在赋值前就被访问的话则会抛出异常
        //println(foo.notNullBar)
    	
        fun member(){ print("member method") }
    
    }
    

    继承类, 接口

    kotlin被继承类必须使用open修饰,否则无法继承

    //open 修饰的类才能被继承
    open class BaseP(var name:String){  
        constructor(name:String,age:Int):this(name){
            println("-------base class construct init---------")
        }
        open fun getName(){ // open修饰方法,才允许子类重写
            println("I'm base class")
        }
    
        fun getHello(){//普通方法无法重写
            //......
        }
    }
    
    //子类继承重写方法
    class Student:BaseP{
        constructor(name:String,age:Int,no:String,score:Int):super(name,age){
            println("-------construct init---------")
            println("name: ${name} age: ${age} num: ${no} score: ${score}")
        }
    
        override fun getName() {
            println("I'm student!")
        }
    }
    

    接口定义及实现:

    //接口定义,接口内可以有非抽象方法或属性
    interface MyInterface {
        val prop: Int // abstract
        val name:String
    
        fun foo(){
            print("MyInterface foo")
        }
    }
    
    //接口实现
    class MyImpl1:MyInterface{
        override val prop: Int
            get() = 18
    
        override val name: String
            get() = "james bond"
    
        override fun foo() {
    //        super.foo()
            print("MyImpl1 foo method")
        }
    }
    

    多接口定义相同方法时,子类实现 对父类调用

    interface IA {
        fun foo() {
            print( "A" )
        }
    
        fun bar()
    }
    
    interface IB {
        fun foo() {
            print( "B")
        }
    
        fun bar() {
            print("bar" )
        }
    }
    
    class D:IA,IB{
        override fun foo() {
            super<IA>.foo()//调用父类IA方法
            super<IB>.foo()//调用父类IB方法
    
        }
    
        override fun bar() {
            super<IB>.bar()
        }
    }
    

    类的扩展:

    Kotlin 除了通过继承,组合等还可以通过自身扩展特性对一个类的属性和方法进行扩展,且不需要继承
    扩展是一种静态行为,对被扩展的类代码本身不会造成任何影响

    class User(var name:String){
    
        fun member(){ print("member: ${name}") }
    	
    }
    
    	//扩展函数
    	fun User.printName(){
    		print("name= $name")
    	}
    	//扩展函数和成员函数一致,则使用该函数时,会优先使用成员函数
    	fun User.member(){
    		print("add member!")
    	}
    

    扩展系统类函数

    //Extension functions
    fun MutableList<Int>.swap(index1: Int, index2: Int) {
        val tmp = this[index1] // 'this' 代表当前扩展对象实例
        this[index1] = this[index2]
        this[index2] = tmp
    }
    

     对一个类的扩展提高了灵活性,同时可以替换部分工具类

    kotlin内有许多扩展实现,如文件扩展,这里实现了元Java FileUtil的功能

    fun handle_file(fileName :String,fileContent :String,fileContentAsArray:ByteArray){
        File(fileName).writeText(fileContent)
        File(fileName).writeBytes(fileContentAsArray)
    
        File(fileName).printWriter().use { out -> out.println(fileContent) }
        File(fileName).bufferedWriter().use { out -> out.write(fileContent) }
    
    //    Reads a file line by line
        File(fileName).forEachLine { println(it) }
        //read all lines
        File(fileName).bufferedReader().readLines()
        //we can convert that into bytes, and then into a complete String
        File(fileName).inputStream().readBytes().toString(Charsets.UTF_8)
        //Reads the entire content of the file as a String
        File(fileName).readText(Charsets.UTF_8)
    
        //手动调用文件写操作
        val ft = File(fileName)
        ft.inputStream().use { input ->
            val result = ByteArray(1024*5)
            var offset = 0
            var remaining = ft.length().toInt()
            while (remaining > 0) {
                val read = input.read(result, offset, remaining)
                if (read < 0) break
                remaining -= read
                offset += read
            }
        }
        //file dir scan
        File("fdir").walkTopDown().forEach { println("${it.path}-isDir:${it.isDirectory}") }
        //file dir1 to dir2
        File("fcopySrcDir").copyRecursively(File("fcopyTarget"),overwrite = true)
        //file dir delete
        File("fdelSrcDir").deleteRecursively()
    
    }

    activity 扩展应用

    fun <T : View> Activity.find(@IdRes id: Int): T {    
        return findViewById(id) as T
    }
    
    
    TextView label = find(R.id.label);
    Button btn = find(R.id.btn);
    

     可以看出扩展之后,编写代码更加便捷了

  • 相关阅读:
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 实现业务
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 开发流程
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 报表系统集成说明
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 处理报表
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 数据访问
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 分布式应用
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 实现插件
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 对象设计器使用帮助
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 数据层开发
    Jquery 中的CheckBox、 RadioButton、 DropDownList、CheckBoxList、RadioButtonList的取值赋值
  • 原文地址:https://www.cnblogs.com/happyxiaoyu02/p/10691388.html
Copyright © 2011-2022 走看看