前几章已经把kotlin最基本的语法、数据结构等说清楚了,接下来这两章主要讲解kotlin中关于类和接口的相关知识
类
类这个东西使用和java比较类似,最简单的如下
class innerClass {
}
再class之前可以加private protected internal 或者public,默认不写就是public了
另外需要注意的是,如果类的内部没有实体,可以直接这么写
class innerClass
不加括号
构造方法
提到类,肯定还会提到他的构造方法
kotlin中的构造方法和java有很大的不同,kotlin的构造方法分为两种:主构造方法、次构造方法
1.主构造方法:
class InnerClass constructor(name: String) {
}
是的,kotlin中的主构造方法,直接就属于类名的一部分,是直接放在类名之后的
constructor就是构造方法的意思,如果主构造方法中没有注解或者可见性修饰符的时候,constructor可以省略不写
class InnerClass(name: String){
}
同时,每个类都提供了一个初始化方法,用于在构造之后,进行初始化
如下:
class InnerClass constructor(name: String) {
var name: String? = null
init {
this.name = name
}
}
另外除了在init中使用,也可以在类本身中使用
class InnerClass constructor(name: String) {
var myName = name
}
class InnerClass(var name: String) {
init {
println(name)
}
}
此时就相当于已经走了初始化、赋值两个步骤
2.次构造方法:
次构造方法和java类似,是放在类里面的
class InnerClass{
constructor(name: String, age: Int){
}
}
此时是当不存在主构造方法时的写法
如果类存在主构造方法,就必须在次构造方法后调用this方法,将方法委托给主构造方法,即如果从次构造方法中进来后,还需要再次进入主构造方法
class InnerClass(name: String) {
constructor(name: String, age: Int) : this(name) {
}
}
次级构造方法可以有很多个,主构造方法只能存在一个
class InnerClass(name: String) {
constructor(name: String, age: Int) : this(name) {
}
constructor(name: String, age: Int, sex: String) : this(name, age) {
}
}
class InnerClass(name: String) {
constructor(name: String, age: Int) : this(name, age, "") {
}
constructor(name: String, age: Int, sex: String) : this(name, age) {
}
}
两个次构造方法相互委托,会出现错误提示:There is a cycle in the delegation calls chain----委托调用链中有一个循环。
再来,我们可以看到在上面的代码中出现了三个name这参数,那么在初始化init的时候,我们调用name是指的哪一个呢?
很明显,指的是主构造方法
class InnerClass(name: String) {
constructor(name: String, age: Int) : this(name) {
}
constructor(name: String, age: Int, sex: String) : this(name, age) {
}
init {
println(name)//这个name指的是主构造方法中的name
}
}
class InnerClass{
constructor(name: String, age: Int) {
}
constructor(name: String, age: Int, sex: String) : this(name, age) {
}
init {
println(name)//这个是会报错的,找不到name
}
}
3.构造方法的可见性
如果像下面这样:
class InnerClass {
}
其实,他是相当于
class InnerClass constructor(){
}
也相当于
class InnerClass public constructor(){
}
默认是public的,这样我们在初始化的时候,可以这样
var inner = InnerClass()
那么就可以这样写
class InnerClass private constructor(){
}
这样,我们就不可以在其他地方构造这个类了
这一点,需要特别记住的
类的构造
刚刚,我们提到了,var inner = InnerClass()
这样的语句,这就是类的构建了,等同于java的
InnerClass inner = new InnerClass();
其他的话,其实和java就没有多大区别呢,如果构造需要参数,直接传入就可以了
var inner = InnerClass(“name”)
类的继承
在kotlin中,类的继承和java差别还是挺大的kotlin的继承使用的是“:”冒号,在kotlin里面,冒号的使用是非常频繁的,继承需要、定义需要、操作需要。
如下:
open class Person{
}
class Man : Person(){
}
然后就是复杂一点的用法:
open class Person(name: String, sex: String) {
}
class Man(name: String) : Person(name, "man") {
}
如果一个父类存在构造方法,并且子类并没有在主构造方法中进行构造,那么就需要在次构造方法中使用super关键字,委托给父类的构造方法
open class Person {
constructor(name: String) {
}
}
class Man : Person {
constructor(name: String) : super(name) {
}
}
open class Person {
constructor(name: String) {
}
constructor(name: String, age : Int){
}
}
class Man : Person {
constructor(name: String) : super(name,0) {
}
}
方法的重写
子类重写父类的方法,和上面一样,也是需要在方法前加open关键字,默认修饰关键字为final
open class Person {
open fun fatherFoo(){
}
}
class Man : Person() {
override fun fatherFoo() {
super.fatherFoo()
}
}
至于里面的super,我就不说了,和java一样
再一个,如果此时有一个类,继承自Man这个类,那么此时fatherFoo这个方法默认就是可以被重写的,就不需要再添加open关键字,默认就是open
open class Person {
open fun fatherFoo(){
}
}
open class Man : Person() {
override fun fatherFoo() {
super.fatherFoo()
}
}
class Child : Man(){
override fun fatherFoo() {
super.fatherFoo()
}
}
final override fun fatherFoo() {
super.fatherFoo()
}
抽象类
类的抽象,如下
abstract class Person {
abstract fun faFoo(): String
open fun getName() {
println(faFoo())
}
}
和java差不多,抽象类和抽象方法前加abstract即可
另外,子类可以使用抽象方法重写父类的一般方法
open class Person {
open fun getName() {
}
}
abstract class Man : Person() {
abstract override fun getName()
}
当然也不能瞎重写,父类的方法都没返回,你抽象方法也是没有返回的
最后提醒一点,抽象类,抽象方法,本来就拿给子类用的,所以,abstract修饰的方法、类,默认自带open
abstract class Person {//这里不需要open关键字,子类也可以继承
abstract fun getName()//这里也不需要open关键字,子类仍然可以重写
}
abstract class Man : Person() {
abstract override fun getName()
}
而这,就是kotlin无敌的人性化了。既然大家都知道这个东西的用法,我们就不再去写出来了
Android开发,Kotlin的了解与学习(七)-----接口与实现