fun main(args: Array<String>) { val p1 = Person() val p2 = Person() p1.age = 10 p2.age = 20 //求p1和p2的年龄和 var plus = p1.plus(p2) println(plus) }//重写“+”方法class Person { var name = "张三" var age = 0 fun plus(person: Person): Int { return age + person.age } }
类的成员
类成员可以访问并且修改,kotlin的类成员变量默认已经实现了get以及set方法。
成员的访问与修改
由于kotlin的类成员变量默认实现get以及set方法,所以类中的成员可以直接调用:
fun main(args: Array<String>) { val stu = Student() println(stu.age) println(stu.name) }class Student { val name = "张三" val age = 15}
修改类成员的可见性
在Kotlin中,若是想要类成员对于外界只能访问不能修改,则在类成员后中写入 private set。若想类成员对外界既不能访问也不能修改,则在类成员前写入private:
class Student { var name = "张三" private set//外界无法修改name private var age = 15//外界无法访问、修改age}
自定义访问器
在我们的例子中,学生的年龄不可能随意设置,比如学生是-1岁,所以需要对设置的数据进行判定,符合一定要求后才能修改。对于此类要求,我们可以用自定义访问器field:
fun main(args: Array<String>) { var person = Student() println(person.age)//20 person.age = 35//由于35>30,所以设置失败 println(person.age)//20}class Student { var name = "张三" var age = 20 set(value) {//value对应传递的age值 if (value > 18 && value < 30) { //可以通过field表示这个字段 field = value } } }
主构函数和次构函数
主构函数
kotlin中主构函数即构造函数,但是无法直接访问构造函数中的元素。如果想要在构造函数里面实现一些操作,需要把代码写在init里:
fun main(args: Array<String>) { val p1 = Person("张三", 23) val p2 = Person("李四", 25) val p3 = Person("王五", 40) println(p1.age)//23 println(p2.age)//25 println(p3.age)//40} class Person(name: String, age: Int) { var name = "" var age = 0 init { this.age = age this.name = name } }
var和val在主构函数参数中的作用
主构函数参数使用var和val,相当于帮我们定义了字段,参数可以直接使用。参数没有var和val修饰,参数在其他地方不能使用 。参数有var修饰,可以使用,也可以修改 。参数有val修饰,只能使用,不能修改 :
fun main(args: Array<String>) { val p1 = Person("张三", 23) val p2 = Person("李四", 25) val p3 = Person("王五", 40) println(p1.age) println(p2.age) println(p3.age) }class Person(val name: String,val age: Int)
次构函数
次构函数必须要调用主构函数,必须要把参数传递给主构函数,且需要用constructor关键字:
class Person2(val name: String,val age: Int){ constructor(name: String, age: Int,phone:String):this (name,age)//调用主构函数将参数传递给主构函数}
次构函数间调用
次构函数可以直接调用主构函数,也可以通过调用次构函数来间接调用主构函数:
class Person3(name:String,age: Int){ //调用主构函数 constructor(name:String,age: Int,phone: String):this(name,age) //通过调用次构函数来间接调用主构函数 constructor(name:String,age: Int,phone: String,qq:String):this(name,age,phone) }
次构函数参数使用
构造函数加var和val只能在主构函数里面加,次构函数中不能加。主构函数参数可以直接加上var和val使用,次构函数只能够自己定义变量进行保存。
class Person3(val name:String,val age: Int){ var phone = "" var qq = "" constructor(name:String,age: Int,phone: String):this(name,age) constructor(name:String,age: Int,phone: String,qq:String):this(name,age,phone){ this.phone = phone this.qq = qq } }
继承
继承是指一个对象直接使用另一对象的属性和方法。kotlin的继承和java中的继承大体相同,但需要注意以下几点:
1.需要将父类加上open关键字
2.需要加上():
kotlin的成员函数和成员变量对应的get以及set方法都有final修饰,不能进行继承,所以要在成员函数和成员变量前加上open关键字才能进行复写:
open class father() { open var name = "小头爸爸" open var age = 40 open fun sayHello() { println("老哥 早上好") } }class son : father() { override var name: String = "大头儿子" override var age: Int = 14 override fun sayHello() { println("同学 早上好") } }
构造函数的继承
构造函数的继承除了通常的操作外,子类也需要构造函数,并且应能在父类中找到对应的字段,还需将函数传给父类。子类也可以用父类的字段:
fun main(args: Array<String>) { var p = Person("张三", 30) var s = Student("李四", 20, "男") println(p.age)//30 println(s.sex)//男 println(s.name)//李四} open class Person(var name: String, var age: Int) { open fun morning() { println("早上好") } }class Student(name: String, age: Int, var sex: String) : Person(name, age) { override fun morning() { println("晚上好") } }
抽象类和抽象方法
父类中的方法,被它的子类们重写,子类各自的实现都不尽相同。那么父类的方法声明和方法主体,只有声明还有意义,而方法主体则没有存在的意义了。我们把没有方法主体的方法称为抽象方法。包含抽象方法的类就是抽象类。抽象类不需要open关键字就可以被调用。
//人类 (抽象类)abstract class Human { abstract var color: String abstract var language: String abstract fun eat() }//具体实现类class Chinese : Human() { override var color: String = "yellow" override var language: String = "chinese" override fun eat() { println("用筷子吃饭") } }class USHuman : Human() { override var color: String = "white" override var language: String = "english" override fun eat() { println("用刀叉吃饭") } }class AfHuman : Human() { override var color: String = "black" override var language: String = "葡萄牙语" override fun eat() { println("用手吃饭") } }
接口
接口的实现是在括号后面加个冒号,然后写上要实现的接口,不需要写interface。若是多个接口,就用逗号“,”隔开。
class men() : bike { override fun rideBike() { println("人骑车") } } interface bike { fun rideBike() }
注意事项
1.java中接口中的字段一定要被赋值,但是Kotlin接口里的字段不能被赋值
2.java接口里面方法不能实现,kotlin可以实现
class men() : Bike, Drive { override val license: String = "123456" override fun drive() { println("人开车") } override fun rideBike() { println("人骑车") } } interface Bike { fun rideBike() } interface Drive { val license: String fun drive() { println("放手刹,踩油门,走") } }
多态
同种功能的不同表现形式。kotlin中的多态原理同java:
abstract class Animal { abstract var name: String open fun bark() { println("动物叫") } }class Dog : Animal() { override var name: String = "旺财" override fun bark() { println("旺财 汪汪叫") } }class Cat : Animal() { override var name: String = "汤姆" override fun bark() { println("汤姆 喵喵叫") } }
智能类型转换
在多态中,多个子类可能均与父类有差别。kotlin中可以通过智能类型推断来判断调用的字段所属于的子类,最终调用所属子类的方法。将父类引用转为子类引用,转换之前还需要判断是否是当前子类类型。一旦判断出是这个类型之后,编译器就把类型转换过去了,不需要手动转换。
fun main(args: Array<String>) { val shepHerdDog: Dog = ShepHerdDog()//将父类引用转为子类引用 //判断是否是当前子类类型 if (!(shepHerdDog is ShepHerdDog)) return //编译器自动转换 shepHerdDog.shepHerd() } abstract class Dogclass ShepHerdDog : Dog() { fun shepHerd() { println("牧羊犬开始放羊了...") } }
嵌套类、内部类
嵌套类默认都是static修饰的,属于静态类,不依赖于外部的环境,即和外部类没有关系:
fun main(args: Array<String>) { val inClass = outClass() }class outClass { var name: String = "李四" class inClass { fun say() { println(name) } } }
内部类需要通过Inner修饰,且需要先创建出来外部环境:
fun main(args: Array<String>) { val inClass = outClass.inClass() }class outClass { var name: String = "李四" inner class inClass { fun say() { println(name) } } }
作者:千里重
链接:https://www.jianshu.com/p/0bc30276de66
共同學(xué)習(xí),寫下你的評(píng)論
評(píng)論加載中...
作者其他優(yōu)質(zhì)文章