kotlin面向对象(基于Java)

kotlin面向对象编程

类与对象

  • 与Java一样,kotlin也使用class关键字来声明一个类

    现在我们创建一个Person类

    class Person{
       var name=""
       var age=0
       fun eat(){
           println(name+" is eating.He is "+age" years old.")
      }
    }

    创建好Person类之后我们需要对它进行实例化并调用

    fun main(){
       val p=Person()
    //p为Person类的一个实例,或者说是一个对象
       p.name="Jack"
       p.age=18
       p,eat()
    }
    //输出:Jack is eating.He is 18 years old.

继承与构造函数

  • 继承

    • 构建一个Student类

      class Student{
         var sno=""
         var grade=0
      }

      因为在kotlin中任何一个非抽象类都默认是不可继承的,相当于了Java中给类声明了final关键字

      (1)所以我们需要在父类Person类前面加上关键字open

      open calss Person{
         var name=""
         var age=0
         fun eat(){
             println(name+" is eating.He is "+age" years old.")
        }
      }

      (2)让Student类继承Person类(在Java中使用的是extents关键字,而在kotlin中使用:即可实现)

      class Student:Person(){
         var sno=""
         var grade=0
      }

      关于Person后面跟着的( ),就需要涉及到我们的构造函数

  • 构造函数

    • 主构造函数

      最常用的构造函数,每个类默认都会有一个不带参数的主构造函数(也可以显示地指明参数)

      主构造函数的特点是没有函数体,直接定义在类名后面即可

      • eg:

        class Student(val sno:String,val grade:Int):
        Person(){
               
          }
        /*因为我们的参数放在了主构造函数当中,那么在对Student的实例化中,必须传入构造函数中要求的所有参数
        val student=Student("202110411xxx",1)
        */

        当我们需要在主构造函数中编写一些逻辑时,使用init结构体

        class Student(val sno:String,val grade:Int):
        Person(){
               init{
                println("sno is "+sno)
                println("grade is "+grade)
              }
          }

        子类中的构造函数必须调用父类中的构造函数

        那么在kotlin中使用括号来进行一个指定:子类中的构造函数调用父类的哪个构造函数,在继承时使用括号进行指定

        class Student(val sno:String,val grade:Int):
        Person(){ }
        //此处Person后的空括号表示Student类的主构造函数在初始化的时候会调用Person中的无参数构造函数

        也就是说,在无参数的情况下。这对括号也不能省略

      • 当我们对Person进行一些改造,如下:

        open class Person(val name:String,val age:Int){ }

        此时的Person类已经没有无参的构造函数了,所以我们需要给Person类的构造函数传入name和grade字段

        class Student(val sno:String,val grade:Int,name:String,age:Int):Person(name,age){ }
        //实例化Student:
        /*
        val student=Student("11xx",1,"Jim",18)
        */
    • 次构造函数

      很少使用,kotlin提供了一个给函数设定参数默认值的功能,基本上可以替代次构造函数的作用

      任何一个类只能有一个主构造函数,但可有多个次构造函数

      次构造函数可以用于实例化一个类,与主构造函数有区别的是次构造函数是有函数体的

      次构造函数通过constructor关键字来定义

      class Student(val sno:String,val garde:Int,name:String,grade:Int):Person(name,age){ constructor(name:String,age:Int):this("",0,name,age){ }
      /*第一个次构造函数接收了name和age参数,然后它又通过this关键字调用了主构造函数,并将sno和grade这两个参数赋值为初始值*/
      constructor():this("",0){ }
      /*第二个次构造函数不接收任何参数,通过this关键字调用了我们刚才定义的第一个次构造函数,并将name和age参数也赋值为初始值*/
      }
      //因为第二个次构造函数间接调用主构造函数,因此仍然合法
    • 特殊情况

      ——类中只有次构造函数,没有主构造函数

      class Student:Person{
         constructor(name:String,age:Int):super(name,age){ }
      }
      //当一个类没有显示的定义主构造函数且定义了次构造函数时,它就是没有主构造函数的
      //因为没有主构造函数,所以继承Person类时也就不需要再加上括号了

      由于没有主构造函数,所以这里的次构造函数就只能直接调用父类的构造函数。所以上述代码也就将前面我们写到的this关键字换成了super关键字来调用父类

接口

与Java相似,kotlin也是单继承结构的语言,任何一个类最多只能继承一个父类,但可以实现任意多个接口

  • 在接口中定义一系列的抽象行为,然后由具体的类去实现

    eg:

    (1)创建一个Study接口

    interface Study{
       fun reaBook()
       fun doHomework()
    }

    (2)让Student类去实现Study接口

    使用override关键字来重写父类或者实现接口中的函数

    class Student(name:String,age:Int):Person(name,age),Study{
       //kotlin中接口使用冒号实现,同时接口后面没有括号(因为它没有供调用的构造函数)
       override fun readBook(){
           println(name"+ is reading.")
      }
       override fun doHomework(){
           println(name+" is doing homework.")
      }
    }

    (3)在main函数中实现接口的调用

    fun main(){
       val stu=Student("Jack",18)
       stu.reaBook()
       stu.doHomework()
    }
  • 为了使接口 的功能更为灵活,kotlin还额外增加了一个功能:允许对接口中定义的函数默认实现

    interface Study{
       fun readbook()
       fun doHomework(){
           println("do homework.")
      }
       //我们给doHomework()函数加上了函数体并打印了一行日志
    }

    如果接口中的一个函数拥有了函数体,这个函数体中的内容就是它的默认实现当调用一个类去实现这个Study接口时,只会强制要求实现readBook( )函数,而doHomework( )函数则可以自由选择实现或者不实现。选择不实现时就会自动使用默认的实现逻辑

函数的可见性修饰符

kotlin中有四种,分别是publicprivateprotectedinternal

需要使用修饰符时直接定义在fun关键字的前面即可

public

在kotlin中是默认项,对所有类可见。

在kotlin中我们定义的没有添加修饰符的函数都是默认是public的

private

与Java一样,只有在当前类中可见

protected

在kotlin中protected关键字表示只对当前类和子类可见,注意区分在Java中该关键字表示对当前类、子类和同一包路径下的类都可见

internal

是kotlin中引入的新的可见性概念,它只对同一模块中的类可见

数据类与单例类

数据类

用于将服务器端或数据库中的数据映射到内存中,为编程逻辑提供数据模型的支持

数据类通常需要重写equals( )、hashCode( )、toString( )这几个方法。

equals( )用于判断两个数据类是否相等

hashCode( )方法作为equals( )的配套方法,需要一起重写,以使用HashMap、HashSet等hash相关的系统类

toString( )用于提供更清晰的输入日志

在kotlin中,我们只需要声明data关键字即可表明这是一个数据类

data class Cellphone(val brand:String,val price:Double)

kotlin会根据主构造函数中的参数将equals( )、hashCode( )、toString( )等固定且无实际逻辑意义的方法自动生成

测试这个数据类方法如下

fun main() {
   val cellphone1=Cellphone.Cellphone("Samsung",1299.99)
   val cellphone2=Cellphone.Cellphone("Samsung",1299.99)
   println(cellphone1)
   println("cellphone1 equals cellphone2 "+(cellphone1==cellphone2))
  }

单例类

用于避免创建重复的对象

在kotlin中,将class改为object后就已经是一个单例类了,可以在里面编写需要的函数

object Singleton {
   fun singletonTest(){
       println("singletonTest is called.")
  }
}
 

而对单例类的调用方法类似于Java中对静态方法的调用

fun main(){
   Singleton.singletonTest()
}



posted @   单身万岁  阅读(94)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示