• Kotlin学习笔记(五)面向对象编程


    面向对象的本质:可以提升抽象的级别,以构建更大,更复杂的系统。简单点说就是,更好的应对需求不断变化的情况。武器就是:抽象!

    这部分只讲和Java不同的一些点。

    1. 构造函数

    一个类可以有一个主构造函数,同时可以拥有多个次构造函数。这是乱的不得了。

    • 主构造函数
    1. 竟然跑到类头去了,直接放在类名的后面。
    2. 参数必须声明类型。
    3. 默认是public。
    4. 如果没有(public/private/protected)修饰,也没有任何注解。 Contructor也可以不写。
    5. 参数可是val,也可以是var。
    6. 可以有初始化值。
    7. 如果继承了一个类,那个类的构造初始化,也可以在类头处理。
    1. class Student Constructor(var name:String, var age:Int){ //默认是public
    2. }
    3. class Student public Constructor(var name:String, var age:Int){
    4. }
    5. class Student private Constructor(var name:String, var age:Int){
    6. }
    7. class Student @AutoWire Constructor(var name:String, var age:Int){
    8. }
    9. class Student(var name:String, var age:Int){ //如果没有(public/private/protected)修饰,也没有任何注解。 Contructor也可以不写。
    10. }
    11. class Student Constructor(var name:String, var age:Int = 20){ //可以有初始化值。
    12. }
    13. class Student public Constructor(var name:String, var age:Int):Person(name){ //如果继承了一个类,那个类的构造初始化,也可以在类头处理。
    14. }
    • init
    1. 由于主构造函数没有函数体。所以初始化放在了init模块中。相当于函数体了。
      1. class Student (var age: Int, var name: String ){
      2. private var mAge: Int
      3. private var mName: String
      4. init {
      5. mAge = age
      6. mName = name
      7. }
      8. }
    2. 除了用init初始化,还可以直接在属性上初始化。
      1. class Student (var age: Int, var name: String ){
      2. private var mAge: Int = age
      3. private var mName: String = name
      4. }
    • 次构造函数

    在类体中,也可以声明前缀有Constructor的构造函数,次构造函数不能有声明val或var。

    1. class Student {
    2. Constructor(name:String, age:Int){
    3. }
    4. }

    如果类既有主构造函数, 又有次构造函数。并且主构造函数初始化了父类的构造函数, 就是用this表示。this可以指代同类的其他构造函数, 这个和Java一样。

    1. class Student(override var name:String, var age:Int):Person(name) {
    2. constructor(name:String, age:Int, weight:Int):this(name, age){ //这个this是主构造函数
    3. }
    4. constructor(name:String) :this(name,20,60) { //这个this是上面那个构造函数
    5. }
    6. }
    7. open class Person(open var name: String) {
    8. }
    • 私有构造函数

    只要如下这么写就可以了,加个private.

    1. class Student private (var name:String, var age:Int){ //主构造函数私有
    2. private constructor(name:String) :this(name,20) {次构造函数私有
    3. }
    4. }
    • 默认构造函数

    和Java一样,默认也有一个无参构造函数。

    • 实例化类

    实例化类是不需要new这个关键词的。很不习惯。

    2. 类的属性

    • Kotlin的类属性都需要手动初始化, 不像java都给你初始化好了,比如基本类型都是初始化0, 对象都是初始化为null。
    • Kotlin的setter/getter,和C#很像,就是有点不伦不类。由于C#和Java一样,属性都是初始化好的,而Kotlin由于需要初始化属性,所以不能像C#一样用大括号括起来。另外,无法制定只重写abstract的getter或者setter。

      1. 当public时,默认就是getter/setter方法。

      1. class Student {
      2. var name: String = ""
      3. var age: Int = 1
      4. }
      5. var student:Student= Student("",1)
      6. student.age =1 //默认自带getter/setter
      7. student.name =""

      2. 下面是自动生成且隐藏的方法。

      1. set(vaule){
      2. field = value
      3. }
      4. get() = field

          3. 当你需要修改getter/setter时,可以这样写:

    1. class Student {
    2. var age: Int = 1
    3. get() = field
    4. set(value) {
    5. if (value < 18)
    6. field = 18
    7. else if (value >= 18 && value <= 30)
    8. field = value
    9. else
    10. field = value - 3
    11. }
    12. }

        4. 当属性有val修饰时,常量为只读属性,  所以只有getter方法。

    • 抽象类与抽象方法

    1. 这一块基本和Java一样。 唯一不一样的地方是,在抽象类中的非抽象方法,默认是final的,不能被重写,如果想被子类重写,必须用“open”修饰。 这样设计,不知道有什么好处。
    2. 在子类被重写的方法要用override修饰。
    • 抽象属性

    由于在Kotlin中,属性是自带getter/setter的,所以就存在抽象属性的概念了。抽象属性在抽象类中不能被初始化,而在子类中必须初始化,否则子类也是抽象类。

    1. abstract class Student {
    2. abstract var name: String
    3. abstract var age: Int
    4. }

    如果子类中有主构造函数,可以在主构造函数里初始化,如下:

    1. class Person(override var name: String, override var age: Int) :Student() {
    2. }

    如果没有主构造函数,就要对抽象属性手动初始化。

    1. class Person : Student() {
    2. override var name: String = ""
    3. override var age: Int =1
    4. }
    • 实现接口

    这一块也差不多和java一样。

    1. 对于父类的包访问权限成员变量,如果子类和父类都在同一个包,则子类可以继承,否则不许。
    2. 当子类和父类的方法一样时,用super来访问父类的方法。
    3. 当有多个一样的父类方法时,用super<具体父类>.来访问方法。

    继承

    所有的类都默认继承Any,有点像Java的Object, 但是又有不同,因为只有equals(), hashcode(), toString()三个方法。不像JAVA Object还有clone/wait/notify/finanlize等。

    枚举类

    Abstruct class Enum():Comparable{

    public final val name:String

    public final val ordinal:Int

    }

    name和ordinal是唯二的两个属性。分别表示枚举对象的值和下标位置。和Java类似。 比较好的是和C#一样,枚举值为自增加一。

    使用enumValues()方法可以遍历打印枚举。

    enum class RGB{

    RED(200), GREEN(100),BLUE(50)}

    }

    val rgbs = enumValues.joinToString{"${it.rgb}:${it.name}:${it.ordinal}"}

    输出rgbs:200: RED:0, 100: GREEN:1,50: BLUE:2

    枚举常量也可以声明自己的匿名类。这种用法以前倒是没见过。

    enum class ActivityLifeState{

    onCreate{

    override fun signal()=onStart()

    }

    abstract fun signal():ActivityLifeState

    }

    var oncreate= ActivityLifeState.onCreate

    oncreate.signal()

    object关键词

    很好的场景就是一些Utils的工具类了。

    Kotlin中没有静态属性和方法,但是可以用object关键词。在类名前加object关键词,就相当于在类型前加了static, 变成了静态类,用法也一样,用类名调用方法和成员属性。而且成员属性默认都是final static的。而且不能实例化object关键词修饰的类。

    把object修饰的类,反编译到Java代码后就容易理解了。

    public final class User{

    private final static String name = "alan";

    private static final User INSTANCE;

    private User(){

    INSTANCE = (User)this

    name ="alan"

    }

    static {

    new User();

    }

    }

    在类中嵌套使用object关键词, 这个用法和java静态类一样。

    匿名object

    有时候仅仅是一个简单的对象,可以用匿名object。但是只能在本地和私有作用域里声明使用。

    class AnonymousObjectType{

    private fun privateFoo()=object{

    val x:String="x"

    }

    fun publicFoo()=object{

    val x:String="x" //无法访问到

    }

    fun test(){

    val x1 = privateFoo().x //正确,WORK

    //val x2 = publicFoo().x//Error

    }

    }

    匿名内部类

    内部类。不再像java那样默认带有外部对象的引用了。

    1. setOnClickListener(object:OnFilteredClickListener(){
    2. override fun onFilteredClick(v: View?) {
    3. TODO("Not yet implemented")
    4. }
    5. })

    未完待续

  • 相关阅读:
    idea2021 创建Servlet模板 & idea2021如何修改Servlet模板
    Redis的两种持久化方式RDB和AOF
    经典算法学习之------冒泡排序
    竞赛选题 深度学习的水果识别 opencv python
    SpringBoot整合easyexcel实现Excl导入导出
    词!自然语言处理之词全解和Python实战!
    交换机基础(二):VLAN 基础知识
    Linux中/etc下面passwd和shadow文件介绍
    UiPath Studio 2023.10 Crack
    肝通宵写了三万字把SQL数据库的所有命令,函数,运算符讲得明明白白讲解,内容实在丰富,建议收藏+三连好评!
  • 原文地址:https://blog.csdn.net/zjuter/article/details/119868163