kotlin面向对象(基于Java)
类与对象
-
与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中有四种,分别是public,private,protected,internal
需要使用修饰符时直接定义在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()
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本