参考
class
class关键字定义一个类。
Any类,Any类中只有hashCode,toString以及equals三个方法。
一个类由类名、类头以及类的主体——被大括号包裹起来的就是类的主体——三部分组成。其中类头,类主体是可选的。如果没有类主体,则大括号可以省略。如:
class Demo //定义一个类,没有类的主体,所以连大括号都可以省略
实例化
跟java类型,只不过将new关键字给除掉。
构造函数
分两种:primary constructor 和secondary constructors。primary只能有一个,而secondary可以有多个。
constructor,并且其可见性为public。
primary constructor与init代码块
constructor关键字定义。如果不需要改变构造函数的可见性,可以将constructor省略。
2,它定义在类名或泛型(如果有泛型)之后。
3,不能写任何代码
init代码块中进行。
5,其参数只可以使用在init代码块以及类成员变量的初始化中。但可以通过var或val为类定义一个同名的变量。
6,如果只使用默认的构造函数,则可以在类名或泛型(如果有泛型)之后加小括号,或者直接什么都不写;但如果添加了constructor关键字,则必须写小括号。
示例一,默认构造函数
class Demo1{//默认构造函数——什么都不写
fun demo(){
println(toString())
}
}
class Demo2(){//默认构造函数——直接写一个小括号,可以在小括号中写参数列表
fun demo(){
println(toString())
}
}
class Demo3 constructor(){//必须写小括号
fun demo(){
println(toString())
}
}
//class Demo4 constructor{//不写小括号会编译失败
// fun demo(){
// println(toString())
// }
//}
示例二,基本使用
class Demo<T> constructor(t : T){//通过constructor关键字指定primary构造函数
init {
t.toString()
}
}
示例三,省略constructor以及不能省略constructor:
fun main(args:Array<String>){
var d = Demo("----")//实例化对象
var d2 = Demo2("----")//此编译时会报错,因为Demo2的构造函数是private,外界不能访问
}
class Demo (t : String){//省略constructor关键字
init {
t.toString()
}
}
class Demo2 private constructor(t : String){//将构造函数指定为private,所以不能省略constructor关键字
init {
t.toString()
}
}
示例四:init代码块:
fun main(args:Array<String>){
var d = Demo("----")
}
class Demo (t : String){//省略constructor关键字
init {
println(t)//在init代码块中进行primary constructor的操作
}
}
示例五:构造函数参数的使用范围
fun main(args:Array<String>){
val a = Adapter(Demo())
}
class Demo{
fun demo():String{
return "this is from demo"
}
}
class Adapter(ctx:Demo) {
val inf = ctx.demo()//使用ctx进行初始化类的成员变量
init{
println(ctx.toString())//ctx使用在init代码块中
}
fun test(){
println(ctx.toString())//编译时会报unresolved reference: ctx——因为ctx是构造函数中参数,只能用在变量初始化或init代码块中
}
}
如果将test()方法中的ctx改为inf,则可以编译通过也可运行。
示例六:定义与构造函数参数同名的变量
fun main(args:Array<String>){
val a = Adapter(Demo())
a.test()
}
class Demo(s:String="default"){
fun demo():String{
return "this is from demo"
}
}
class Adapter(val ctx:Demo) {//添加一个val或var关键字,则该类会自动生成一个ctx成员变量,所以该类中的各个方法中均可使用该ctx
fun test(){
println(ctx.toString())//可以使用ctx,因为Adapter类中有一个名为ctx的成员变量
}
}
反编译Demo与Adapter对应的class文件,如下:
从中很容易看出变量名前添加var或val与不添加的区别。
Secondary Constructors
1,可以有多个
constructor定义
this指代别的构造函数。
4,无论定义多少个Secondary,primary一定存在。
示例一,通过this指定别的构造函数
fun main(args:Array<String>){
Demo1("first2","22")
}
class Demo1{//默认无参的primary构造函数
init{
println("init 块")//最先执行
}
constructor(a:String){//其代理了primary,只不过primary是无参的
println("one a=$a")//第二个执行
}
constructor(a:String,b:String):this(b){//代理一个参数的构造函数,并且将参数b传递到该构造函数中
println("two a=$a,b=$b")//最后执行
}
}
示例二,有参的primary
class Demo1(d:Int){
init{
println(d)
}
constructor(a:String):this(3){//必须通过this来代理primary,同时为其传递参数,这里直接传递具体参数值
println("one a=$a")
}
constructor(a:String,b:String):this(b){//将参数b的值传到到构造函数中,并没有传递具体的参数值
println("two a=$a,b=$b")
}
}