Kotlin学习:类、对象、接口

Kotlin Class, object, and interfaces

Kotlin中的接口:interface关键字 不同于java方法的implement和extends,kotlin使用的是冒号: 来完成这个方法。 也不同与java的注释override,我们使用关键词override来强制实现。

接口默认实现:

interface Clickable{
    fun click() // 方法声明
    fun showOff() = println("i am clickable") // 接口默认实现
}
复制代码

对于接口默认实现的方法:

  1. 我们可以直接使用
  2. 我们也可以重写这个方法
interface Focusable{
    fun setFocus(b: boolean) = println("I ${if(b) "got" else "Losr"} focus")
    
    fun showOff() = println("i'm foucusable! ")
}
复制代码

如果一个类实现了多个接口,而多个接口却有相同的方法,我们需要具体指定实现哪一个方法

class Button: Clickable, Focusable{
    override fun click() = println("I was clicked")
    
    override fun showOff(){
        super<Clickable>.showOff()
        super<Focusable>.showOff()
    }
}
复制代码

final by default

kotlin中的类默认都是final ,在Effective java中提到了一点:『design and document for inheritance or else prohibit it』

// 这个类可以被其他类继承
open class RichButton: Clickable {
    fun disable(){} // fun 默认是final 表示这个方法可以被复写
    open fun animate(){} // open fun 表示你可以复写这个方法
    override fun click(){} // 这个方法复写一个open fun 它同样也是open fun 可以被人复写
    final override fun click1(){} // 但是被final修饰了 所以不可以被其他复写
}
复制代码

abstract

和java一样 abstract表示的是这个类不可以被实例化,一个抽象类可以包含抽象对象和抽象方法,抽象类中的所有的方法都是open

abstract class Animated{
    abstract fun animate()
    
    open fun stopAnimating(){}
    
    fun animateTwice(){}
}
复制代码
modifiercorresponding memberComments
finalcan't be overriddenUsed by default
openCan be overriddenShould be specified
AbstractMust be overriddenCan be used only in abstract class
overrideoverrides a member in superclassOverrideen member is open by default if not marked final

pubic by default

kotlin只有三个标识修饰关键字:public protected private。 去掉了java中的package-private,在Kotlin中packages只是在namespace中来组织代码而已。

modifierclass memberTop-level declaration
publicvisible everywhereVisible everywhere
Protectedvisible in subclassed
privatevisible in a classvisible in a file

Inner And nested class: nested by default

Kotlin中的嵌套类不能访问外部类的对象实例,

interface State : Serializable
interface View{
 	fun getCurrentState() : State
    fun restoreState(state: State){}
}

public class Button implements View{
    public State getCurrentState(){
        return new ButtonState();
    }
    
 	public void restoreState(State state){}
    public class ButtonState implement State{}
}
复制代码

在很多常见的场景,我们都需要创建一个内部类来存储外部类的状态,在上面的代码中当我们调用getCurrentState()来序列化我们会报错,因为这里面有一个问题便是 内部类ButtonState实现了State这个可以序列化的同时其实它还隐藏的持有了外部类的引用 因为Button没有实现序列化的接口导致报错。

class A declared whthin another class BIn JavaIn Kotlin
Nested classState class Aclass A
Inner classclass AInner class A

sealed 关键字

我们都知道enum枚举 表示有限的集合,但是enum对应的其实是基本数据类型。在kotlin中类的表达其实是sealed,两者高度相似。

类中的constructor

kotlin中的构造函数分为两种,因为kotlin中允许可以默认参数 所以kotlin的写法中不太需要过载方法 一般只需要设置一些默认参数就可以

// kotlin中的原创写法 简洁不少 去掉了constructor 同时不用申明变量
class User(val nickName: String)

// 想java一种使用关键词constructor init super this
class User constructor(_nickname: String){
    val nickname:String
    //此处初始化可以多次使用 按照声明的顺序按顺序执行
    init{
        nickname = _nickname
    }
    
    init{
        nick
    }
}

class MyButton : View{
    constructor(ctx: Context):super(ctx){
        
    }
}

复制代码

interface中的变量

interface User{
    val nickName: String
}
复制代码

接口中的声明的变量如何去初始化

class PrivateUser(override val nickname:String) :User

class SubscribeingUser(val email: String) : User{
    override val nickname;String
    	get() = email.substringbefore('@')   
}

class FaceBookUser(val accountId: Int) : User{
	override val nickname = getFacebookName(accountId)
}
复制代码

类的装饰模式 by 关键字

class DelegatingCollection<T>(innerList: Collection<T> = ArrayList<T>()):Collection<T> by innerList
复制代码

类的单例模式 object 关键字

  1. 类的单例模式
object Payroll{
    val allEmployees = arrayListOf<Person>()
    
    fun calculateSalary(){
        for(person in allEmployees){
            
        }
    }
}
复制代码

object 中的对象没有所谓的构造器,对象的生成在定义的时候就会立即生成,而不是通过偶在函数来生成的

object的对象的调用之间使用 . 即可,这一点和javascript中的字面对象有点像

Payroll.allEmployees.add(Person(...))
Payroll.calculateSalary()
复制代码

Object 对象也可以被类继承和接口实现。

  1. Static 静态方法和对象

    直接创建一个工厂模式 也就是所谓的静态方法

    class User(val nickname: String){
        companion object{
            fun newBeginingUser(email:String) = User("")
            fun newFacebookUser(accountId: Int) = User(account)
        }
    }
    复制代码

    使用方法:

    val subscribeingUser = User.newBeginingUser("bob@email.com")
    val facebookUser = User.newFacebookUser(3)
    复制代码
  2. 匿名内部类

    Object可以充当一个匿名内部类来使用

    window.addMouselistener(object: MouseAdapter(){
        ...
    })
    复制代码

Summary

  • Interface 在Kotlin中和Java类似 除了可以拥有默认的方法实现和属性
  • 所有的声明默认都是 final public
  • 想让声明不是final 需要使用关键open
  • Nested class 默认是不外部类有引用关系, 可以使用关键字 inner 来内部类与外部类有引用关系
  • 关键字 sealed 可以将有限的子类包含在父类中(在when 中可以去掉else 因为包含了所有的可能性)
  • 除了 第一构造函数外,我们还有 init constructor 来灵活初始化对象
  • field 可以提供便捷的对象的set() get()方法的使用
  • data 也就是所谓的Javabean 关键字可以提供 equals hashCode toString copy 等便捷的方法
  • by 关键字可以提供类似代理模式
  • object 关键字 可以提供单例模式
  • companion object 替代了java所有的静态方法和属性定义
  • object 关键字可以替代java中的匿名内部类
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值