赞
踩
fun main() {
var a = A() // 面相函数式,所以不用new关键字也可以
a.print()
}
class A {
val a = 2
fun print() {
println(a)
}
}
在kotlin中,不能直接调用get和set方法,默认就是赋值就自动调用了set()方法,取值就自动调用get()方法。
就像下面这段示例,test.a = 5这个赋值操作调用set(),取值调用get():
fun main() { var test = A() test.a = 5 test.print() } class A { var a = 2 get() { return field - 1 } set(value) { field = value + 1 } fun print() { println(a) } }
输出结果:
我们可以在类中添加初始化函数,每当创建一个类的对象之后,init方法就会自动调用,可以用于初始化数据
fun main() {
var test = A()
}
class A {
var a = 2
init {
println("A") //自动调用
}
}
通过传入值初始化:
fun main() {
var test = A(5)
}
class A(b: Int) {
var a = 2
init {
a = b
}
}
值得注意的是:在对对象传入值的之后可以同时对变量初始化,例如:
class A(var b: Int) {}
,就代表了b就成为了A对象的成员变量,kotlin语法支持这样写。但是只能在一级构造函数(主构造函数)上写这种,在二级构造函数中不支持这种语法,二级构造函数接下来有介绍。
在kotlin中奖构造函数分为主构造函数和次构造函数
class A constructor() {
var a = 2
init {
// 主构造函数的方法体
}
}
其中,主构造函数关键字constructor可以省略不写,其构造的方法体就在init函数中。
class A constructor(var b: Int = 1) {
var a = 2
init {
println("init()...")
}
constructor() : this(3) { //代理主构造函数
println("次构造函数...")
}
}
注意:次构造函数需要主构造函数调用才能实现,即使用
this()
代理主构造函数,也可以传入参数this(3)
,可就是将b赋值为3。
这种方式就相当于java中的在构造方法中调用其他构造方法。
class A constructor(var b: Int = 1) {
var a = 2
init {
println("init()...")
}
constructor(c: Int, d: Int) : this(3) {
println("次构造函数1...")
}
constructor() : this(1, 2) {
println("次构造函数2...")
}
}
当然,次构2不一定要代理次构1,也可以直接代理主构,但是次构1就失效了。
例如这种,就直接成为主构造函数了:
class A {
constructor(c: Int, d: Int) {
//此时识别为主构造函数
}
}
多态:
class A {
constructor(c: Int, d: Int) {
}
constructor(c: Int) {
}
}
fun main() { var b = B() b.print() } open class A { //一定一定要添加open关键字 var a = 1 } class B : A() { var b = 2 fun print() { println(a) println(b) } }
一定一定要添加open关键字。
子类继承父类,子类要对父类进行构造方法的初始化:
1、主构造函数初始化:
open class AParent {
}
class AChild() : AParent() {
}
2、次构造函数初始化:
open class AParent {
}
class AChild : AParent {
constructor() : super(){}
}
3、父类多构造函数–子类主构造函数调用 :
当父类函数存在两个构造函数时,分别为主构造函数和二级构造函数:
open class AParent(name: String, age: Int) {
constructor(name: String) : this(name, 30)
}
子类函数2:
class AChild() : AParent( "A") {}
子类函数1:
class AChild() : AParent( "A",15) {}
上述两种方式都可以实现父类构造函数的初始化,图解:
3、父类多构造函数–子类副构造函数调用 :
赋值输出:
fun main() {
var aChild = AChild("rediaz")
aChild.print()
}
open class AParent(var name: String, var age: Int) {
constructor(name: String) : this(name, 30)
}
class AChild : AParent {
constructor(name: String) : super(name)
fun print(){
println("name: ${super.name}")
}
}
正常继承,默认无法进行重写:
它说需要override关键字,好嘛加上:
然后又说基类的方法关键字是final修饰的。
正确重写方式,在父类的成员方法中加上open关键字:
open class AParent() {
open fun A() { println("A") }
open fun B() { println("B") }
}
class AChild : AParent() {
override fun A() {}
override fun B() {}
}
这个是kotlin中特有的操作,Java中没有。
示例:
open class AParent() {
open val a = 1
open var b = 2
}
class AChild : AParent() {
override val a: Int
get() = super.a
override var b: Int
get() = super.b
set(value) {}
}
上述这种方式就实现了重写属性成员a和b,其中a是常量,b是变量,所以重写之后有点区别。
重写的时候可以直接赋值进行覆盖:
open class AParent() {
open val a = 1
open var b = 2
}
class AChild : AParent() {
override val a: Int = 0
override var b: Int = 0
}
但是底层还是有get和set方法
重写时将a的val换成var,则其会将代码编译成新的变量,并生成对应的get和set方法:
对于抽象类,其用法与Java无异
抽象是面向对象编程的特征之一,类本身,或类中的部分成员,都可以声明为abstract的。抽象成员在类中不存在具体的实现。
需要注意的是:不用对抽象类或抽象成员标注open注解。
abstract class AParent() { // 抽象类
abstract fun sum() // 抽象方法
}
class AChild : AParent() {
override fun sum() {
}
}
先上代码:
fun main() { var aParent = AParent() aParent.print() var aChild = AParent.AChild() aChild.print() } class AParent() { // 抽象类 fun print() { println("外部类") } class AChild() { fun print() { println("嵌套类") } } }
注:在Java中,这是一个内部类的一个写法,但是在koltin中,这种事属于内部类的一个写法。
嵌套类是被final关键字修饰的。
在嵌套类的基础上,在嵌套类的前面加上一个关键字inner就变成了内部类,并且可以访问外部类中的成员变量,使用this@类名
的方式。示例:
fun main() { AParent().AChild().print() } class AParent() { val a = 1 fun print() { println("外部类") } inner class AChild() { //加上inner关键字 fun print() { println("嵌套类") println(this@AParent.a) //获取AParent中的a值 } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。