参考链接

类定义格式

使用class关键字定义,格式如下:

class T{
//属性
//构造函数
//函数
//内部类
}

Java Bean类

java bean类

//java bean类
public class Student {
private String name;
private int age; public Student() {
} public Student(String name) {
this.name = name;
} public Student(String name, int age) {
this.name = name;
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
}
}

java bean类(kotlin实现)

//kotlin写法,get和set方法默认实现
class Student {
/注意,这里的var代表着变量的数值之后可以被修改,也可以使用只读val
//?是可为空的写法,后面会提到
//这里其实包含了主构造方法,不过因为主构造方法为空,所以省略了
var name: String? = null
var age: Int = 0 //这几个constructor是次级构造方法
constructor() {} constructor(name: String) {
this.name = name
} constructor(name: String, age: Int) {
this.name = name
this.age = age
} } //下面是没有省略主构造方法的
//注意,因为把默认的主构造方法写了出来,所以,不允许出现无参数的次构造方法
class Student public constructor() {
//注意,这里的var代表着变量的数值之后可以被修改,也可以使用只读val
//?是可为空的写法,后面会提到
//这里其实包含了主构造方法,不过因为主构造方法为空,所以省略了
var name: String? = null
var age: Int = 0 //这几个constructor是次级构造方法
constructor(name: String) : this() {
this.name = name
} constructor(name: String, age: Int) : this(){
this.name = name
this.age = age
}
}

主函数调用

//主函数调用
fun main(args: Array<String>){
//声明类不需要new关键字
val student = Student("star",12)
//,使用对象.属性名调用,而不是使用get或set
println(student.age)//获得属性
student.name = "stars"//修改属性
}

主构造方法(kotlin)

kotlin类中可以有主构造方法和次构造方法,次构造方法也就是上面那段使用kotlin实现的Java Bean类(上面的主构造方法其实是省略了的)

/*下面三种方法都是声明了一个Student类
*Student包含了一个构造方法(两个参数),还有两个成员变量以及成员变量对应的get和set方法
*/ //原始方式,使用主构造方法
class Student public constructor(name: String,age: Int) {
//注意,这里的var代表着变量的数值之后可以被修改,也可以使用只读val
var name = name
var age = age
} //简洁写法,如果主构造方法只有默认的修饰符(public,默认的修饰符可省略),可以把constructor省略
class Student(name: String,age: Int) {
var name = name
var age = age
} //更简洁写法
class Student(var name: String,var age: Int) {
} //使用Student类
fun main(args: Array<String>) {
//声明类不需要new关键字
val student = Student("star",12)
println(student.name)
println(student.age)
student.age = 19 //修改内容
println(student.age)
}

init(初始化块)

如果我们想要在主构造方法进行初始化操作,需要在init代码块里面写我们的代码,如

//更简洁写法
class Student(var name: String,var age: Int) {
init{
println("这里是初始化操作")
}
}

注意,初始化块是主构造方法的一部分

初始化操作会在次构造方法之前执行,即使没有写主构造方法,如:

class Student{
var name: String? = null
var age: Int = 0 init{
println("这里是初始化操作")
} constructor(name: String, age: Int) {
this.name = name
this.age = age
}
}

主/次构造方法联合使用

类定义了主构造器,次构造器必须直接或间接调用主构造器;

class Student() {
var name: String? = null
var age: Int = 0 //这几个constructor是次级构造方法,,这里的this()就是当前的主构造方法
constructor(name: String) : this() {
this.name = name
} constructor(name: String, age: Int) : this(){
this.name = name
this.age = age
}
}
class Student public constructor() {
var name: String? = null
var age: Int = 0 //这几个constructor是次级构造方法,,这里的this()就是当前的主构造方法
//这里用专业术语说,是次级构造方法需要委托给主构造方法
constructor(name: String) : this() {
this.name = name
} constructor(name: String, age: Int) : this(){
this.name = name
this.age = age
}
}

伴生方法(静态方法)

class Student{
...
companion object {
@JvmStatic
//下面定义一些方法
fun sayHello() {
println("hello")
}
}
}

get/set方法修改

看完上面,我们都知道kotlin默认帮我们实现了get和set方法,val修饰的变量是只读的,所以该变量没有setter方法

格式:

var <propertyName>[: <PropertyType>] [= <property_initializer>]
[<getter>]
[<setter>]
//表达式写法
get() = ...
//花括号写法
get(){
...
return xx
}
class Student() {
var name: String = ""
var age: Int = 0
//这里使用val
val isNameEmpty: Boolean
get() = name.length==0 //使用var就得赋值
//val isNameEmpty: Boolean
// get() = name.length==0 constructor(name: String) : this() {
this.name = name
} constructor(name: String, age: Int) : this(){
this.name = name
this.age = age
}
}

如果要在get和set引用当前的字段(属性值),得使用filed关键字代替内容

class Student() {
var name: String = ""
//如果当前的name为"",则返回小红作为姓名
//这里的filed就是name,类型也与name一样
get() {
return if(field.length==0) "小红" else field
}
var age: Int = 0 constructor(name: String) : this() {
this.name = name
} constructor(name: String, age: Int) : this(){
this.name = name
this.age = age
}
}

setter方法与之前的getter方法一样,里面也是使用field代替当前的数值,只不过setter有一个参数,默认为value,可以修改名字

set(value){
filed = vaule
}

嵌套类和内部类

嵌套类和内部类的区别是,嵌套类无法引用外层类的属性和方法,而内部类可以

//Nested为嵌套类
class Outer {
private val bar: Int = 1
class Nested {
//这里因为是嵌套类,无法引用Outer中的bar
fun foo() = 2
}
} val demo = Outer.Nested().foo() // == 2

内部类,使用inner关键字

class Outer {
private val bar: Int = 1
inner class Inner {
//这里可以引用bar
fun foo() = bar
}
} val demo = Outer().Inner().foo() // == 1

继承和接口

继承

kotlin所有的类都是继承于Any,注意,Any 并不是 java.lang.Object

kotlin中的类默认是不可继承的,需要有open关键字修饰类,需要在子类复写的方法,也得在父类用open修饰该方法

open class Person{
var name: String = ""
var age: Int =0 constructor(){}
constructor(name: String, age: Int){
this.name = name
this.age = age
} open fun hello() {
println("hello this is person")
}
} class Student: Person {
constructor() : super(){}
constructor(name: String,age: Int) :super(name,age){} override fun hello() {
println("hello this is student")
}
}

接口

接口的实现也是使用:,声明接口也是interface关键字,注意,kotlin中的接口方法可以实现

interface Print {
fun print()
fun say(){
println("sayhello")
}
}

Student类继承Person并实现Print接口:

class Student: Person,Print {
override fun print() {
//复写接口里的方法
} constructor(name: String,age: Int) :super(name,age){} override fun hello() { }
}

数据类

介绍

kotlin提供了一个数据类,专门类存放数据,使用关键字data修饰类

官方的关于数据类的规范:

  • 主构造函数需要至少有一个参数;
  • 主构造函数的所有参数需要标记为 val 或 var;
  • 数据类不能是抽象、开放、密封或者内部的;
  • (在1.1之前)数据类只能实现接口。

数据类主要有下面两种特点:

  • 自动解析
  • 直接复制

数据类定义

data class Person(var name: String,var age: Int){
}

解构

解构有顺序,顺序根据类中属性的属性

kotlin1.1开始支持使用"_"跳过不需要的变量

val person = Person("star",19)
//val括号里可以根据需要选择不同参数,注意顺序
val(name,age) = person
println("$name, $age years of age") // 输出 "star, 19 years of age"
//跳过name
val(_,age) = person
println(age)

复制

val person = Person("star",19)
val person1 = person.copy()
//复制并修改部分属性
val person2 = person.copy(age =23)

总结

个人觉得,如果某个类只有一个构造方法,可以定义类只含有一个主构造方法即可,使用那个最简洁的方式。

如果需要有不同参数的构造方法(或者是Java Bean),则使用次级构造方法

如果是用来当做数据类,则使用数据类定义

最新文章

  1. TYPESDK手游聚合SDK服务端设计思路与架构之三:流程优化之订单保存与通知
  2. ElasticSearch部署安装
  3. 初探linux内核编程,参数传递以及模块间函数调用
  4. 评价软件_搜狗输入法(pc端)
  5. Python之路-(三级菜单)
  6. 华农js抢课神器
  7. linux2.6中的工作队列接口 workqueue_struct
  8. JSON Date Format/JSON 日期格式方法分享
  9. DES加解密实现方式
  10. 【Python】考虑用生成器改写直接返回列表的函数
  11. Java 之 反射
  12. 【转】为什么delete以后指针还能被赋值
  13. ERROR Fatal error during KafkaServer startup. Prepare to shutdown (kafka.server.KafkaServer)
  14. Mac 启用NTFS
  15. IDEA一定要懂的32条快捷键
  16. 钢琴培训班课程、课时及费用管理系统已提供ACM3.0新版下载
  17. Linux 应用——常用函数(usual function)
  18. oracle数据库组件列表及相关的数据字典视图
  19. Cookie的存活时间
  20. ie浏览器的版本

热门文章

  1. hadoop之hbase基本操作
  2. 报错:java.sql.SQLException: The server
  3. while循环语句、格式化输出、常用运算符、字符编码
  4. 监控redis的操作命令
  5. 教你用VMware Workstation Pro 12 安装XP系统
  6. eclipse中一个项目引用另一个项目,运行报:java.lang.NoClassDefFoundError
  7. HDU 2888:Check Corners(二维RMQ)
  8. Java中实现线程的方式
  9. 图片懒加载,Selenium,PhantomJS
  10. Azkaban Condition Flow (条件工作流) 使用简介