[kotlin]面向对象之继承,重载(跟java的设计很不一样)

我一直在想如何写好这一篇文章,因为此章节应该比之前面的章节更有价值,内容更加有趣,学习的其中一个乐趣在于看完一个理论,又在另外一个地方看到了理论的实践,随着开发经验的增加,发现技术并不是井喷式的增加,而是破冰式的,怎么说呢,技术在某个地方都有着相似的地方,看完koltin的继承,重载设计,还有很多关键字如 open ,override, final就不得不佩服koltin的设计��,因为它在很多程度上遵守了《effective java》里面的items,下面容我娓娓道来��。

// 在kotlin中, 所有类在默认情况下都是无法被继承的,
// 在kotlin中,所有类默认情况都是final的
// open的含义与final相反
open class Parent(name: String, age: Int){

}

class Child(name: String, age:Int): Parent(name, age) {

}

open class Parent2(name: String){

}


/**
 * 在kotlin中,如果一个类没有primary构造方法,那么这个类的secondary构造方法就需要通过
 * super关键字来初始化父类型,或者通过其他secondary 构造方法完成这个任务
 * 不同的secondary构造方法可以调用父类型的不同的构造方法
 */
class Child2: Parent2{
    constructor(name: String): super(name){
    }
}
  • 在kotlin中,所有类在默认情况下都是无法被继承的
  • 在kotlin中,所有类默认情况都是final的,field, fun都是final的��
  • open关键字跟final关键字想法
    死记硬背这些条约其实没有意思,真正的理解背后设计的意义
    effective java中item15 minimize the accessibility of classes and members
    约束条款阐述如下
    1.好的组件设计是不对外暴露实现细节(另外的组件只能通过api来访问)
    2.一个好的组件需要隐藏自己的细节,而提供一个简洁的对外API
    3.公共的类中不要提供公共的field.保证public final 的成员是immutable的
    item17 minimize mutability
    优点这里不做阐述,java在这方便做的不好,我们喜欢用继承,但是用好继承的人很少,反而会造成系统的bug,程序员们不知道怎么样去安全的继承一个类,父类的设计,我们更倾向于安全的设计,所以koltin默认是final的,所有的内容不加open都是final,不推荐子类中使用,这样也很直观
    上面例子最后阐述了子类在没有primary构造函数继承的时候如何通过secondary构造方法直接或者间接完成任务
    下面在看一个例子,验证文字描述
open class Fruit{
    open fun name(){
        println("fruit")
    }

    fun expirationDate(){
        println("1 month")
    }
}

class Apple: Fruit(){
    override fun name(){
        println("apple")
    }
}

open class Orange: Fruit(){
    //orange name不可以被子类改写的
    final override fun name() {
        println("orange")
    }
}

fun main(args: Array<String>) {
    var apple = Apple()
    apple.name()
    apple.expirationDate()
}

open class MyParent{
    open val name: String = "parent"
}

class MyChild : MyParent() {
    override val name: String = "child"
}

fun main(args: Array<String>) {
    var myChild = MyChild()
    println(myChild.name)

    println("----")

    var myChild3 = MyChild3()
    myChild3.method()
    println(myChild3.name)
}

class MyChild2(override val name: String) : MyParent() {

}

open class MyParent3{
    open fun method() {
        println("parent method")
    }


    open val name: String get()= "parent"
}

/**
 * 1.val 可以 override val
 * 2.var 可以 override val
 * 2.val 不可以 override var
 * 本质上 val相当于get方法, var相当于get和set方法
  */
class MyChild3: MyParent3(){
    override fun method() {
        super.method()

        println("child method")
    }

    override val name: String
        get() = super.name + "and child"
 }

这里var修饰的 get()方法,不能被val修饰的成员变量重载,原因是,子类不能缩小父类的读写权限

effective java对于后端程序员如圣经般的存在,需要好好研读:innocent:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值