Kotlin学习3-类(嵌套/内部类,数据/静态类)

一般类形式:

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 = [email protected] //获取外部类的成员变量
            //内部类引用外部类成员
            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
}

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

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);

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

原文地址:https://www.cnblogs.com/happyxiaoyu02/p/10691388.html

时间: 2024-08-30 14:03:46

Kotlin学习3-类(嵌套/内部类,数据/静态类)的相关文章

学习日记(十二)java嵌套类和内部类

嵌套类和内部类:在一个类里边定义的类叫做嵌套类,其中没有static修饰的嵌套类是我们通常说的内部类,而被static修饰的嵌套类不常用.有的地方没有嵌套类和内部类的区分,直接是嵌套类就称作内部类,没有嵌套类的说法.而通常我所听说的基本上都是直接说的内部类,可能这种说法更为常见一些. 内部类的范围由装入它的类的范围限制,内部类可以访问外部类的成员,包括private修饰的,因为它被当成了外部类的成员,一个类的成员之间是可以相互访问的,但是反过来外部类不能访问内部类的实现细节. 内部类可以被定义在

深入理解java嵌套类和内部类

一.什么是嵌套类及内部类 可以在一个类的内部定义另一个类,这种类称为嵌套类(nested classes),它有两种类型:静态嵌套类和非静态嵌套类.静态嵌套类使用很少,最重要的是非静态嵌套类,也即是被称作为内部类(inner).嵌套类从JDK1.1开始引入.其中inner类又可分为三种: 其一.在一个类(外部类)中直接定义的内部类: 其二.在一个方法(外部类的方法)中定义的内部类: 其三.匿名内部类. 下面,我将说明这几种嵌套类的使用及注意事项. 二.静态嵌套类 如下所示代码为定义一个静态嵌套类

Java中的嵌套类和内部类

以前看<Java编程思想>的时候,看到过嵌套类跟内部类的区别,不过后来就把它们的概念给忘了吧.昨天在看<数据结构与算法分析(Java语言版)>的时候,又遇到了这个概念,当时就很大的疑惑:嵌套类跟内部类有什么区别?只有是否有关键字static的区别吗? 所以今天找了个时间查了一下两者的详细区别,总结在这篇博客中,既方便自己的复习和学习,也启示他人吧. 1,概念: 定义在一个类内部的类,叫作"嵌套类".嵌套类分为两种:static的和非static的.后者又有一个专

Java学习笔记(七):内部类、静态类和泛型

内部类 在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类.广泛意义上的内部类一般来说包括这四种:成员内部类.局部内部类.匿名内部类和静态内部类.下面就先来了解一下这四种内部类的用法. 成员内部类 成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员). 1 class Circle { 2 private double radius = 0; 3 public static int count =1; 4 public Circ

JAVA 嵌套类和内部类

一.什么是嵌套类及内部类?  可以在一个类的内部定义另一个类,这种类称为嵌套类(nested classes),它有两种类型:  静态嵌套类和非静态嵌套类.静态嵌套类使用很少,最重要的是非静态嵌套类,也即是被称作为  内部类(inner).嵌套类从JDK1.1开始引入.其中inner类又可分为三种:  其一.在一个类(外部类)中直接定义的内部类;  其二.在一个方法(外部类的方法)中定义的内部类;  其三.匿名内部类.  下面,我将说明这几种嵌套类的使用及注意事项. 二.静态嵌套类  如下所示代

面向对象学习【类-静态类】

静态类只能包含静态成员(使用该类创建的所有对象将共享这些成员的同一个副本).静态类纯粹作为工具方法和字段的一个容器来使用.静态类不能包含任何实例数据或方法.另外,使用new操作符来创建静态类的一个对象是没有意义的.如果坚持这样做,编译器会报错.如果需要执行任何初始化,那么static类可以包含一个默认的构造器,前提是该构造器也被声明为static.其他任何类型的构造器都是非法的,编译器会报错: 比如自己定义一个Math类,其中只包含静态成员,那么应该像下面这样写: public static c

Java中的嵌套类、内部类、静态内部类

在Java中我们在一个类的内部再定义一个类,如下所示: class OuterClass { ... class NestedClass { ... } } 那么在上面的例子中我们称OuterClass为外围类(enclosing class),里面的那个类称之为嵌套类(Nested Class). 嵌套类可以分为两种,静态的和非静态的,即静态嵌套类和非静态嵌套类.非静态嵌套类又叫做内部类(Inner Class).我们通常所说的静态内部类其实是不严格的,严格的说应该叫做静态嵌套类(Static

Kotlin学习与实践 (四)类、接口

1.类的继承结构 接口 * Kotlin的类和接口与Java的有些地方不一样:* Kotlin的声明默认是public final的.* Kotlin嵌套的类默认不是内部类:它没有包含对外部类的隐式引用 等* Kotlin也一样是使用interface来声明接口 * 如下: 声明一个简单的接口 interface Clickable { fun click() fun longPress() = println("longPress") //接口中的抽象方法也可以有默认的实现,有了默认

Cocos2d-x 3.1.1 学习日志3--C++ 初始化类的常量数据成员、静态数据成员、常量静态数据成员

有关const成员.static成员.const static成员的初始化: 1.const成员:只能在构造函数后的初始化列表中初始化 2.static成员:初始化在类外,且不加static修饰 3.const static成员:类只有唯一一份拷贝,且数值不能改变.因此,可以在类中声明处初始化,也可以像static在类外初始化 #include <iostream> using std::cout; using std::endl; class base { public: base(int