美文网首页
Kotlin中的接口,谁说接口不能有实现代码

Kotlin中的接口,谁说接口不能有实现代码

作者: 逸群_9c5c | 来源:发表于2017-12-06 13:49 被阅读0次

    本文链接
    本文结合自己的感受,做一下简单的翻译。原文作者也是《Kotlin for Android developer》的作者。此译文供大家学习参考之用。

    Kotlin中的接口,谁说接口不能有实现代码

    相比Java,用Kotlin写的接口允许你复用更多代码。理由很简单:你可以加实现代码到接口中。如果你在Java8中尝试,也是类似的。在接口中加实现代码是一件不错的事情,这是你能使用更多强大的代码组合方式。然后我们接下去看看。

    Java 6中的接口

    Java接口的问题是我们只能定义描述行为,但是不能有实现。很多的时候,这够了,但是如果我们要达到更好的组合方式,由于强制我们把接口的实现委托给实现对象,这些情况不能解决。这样使得本来简单组合一下可重用代码片段就能解决的问题,变的复杂化了。

    Kotlin中使用接口

    Kotlin带给我们一些好消息:接口可以有实现代码。这个意味着我们能实现一种类的多重继承(有些例子中有部分限制)。我们能让一个类实现几个接口,从每个接口继承行为(有实现代码)。(Java中的类不能多重继承类,这是一个很大的限制)

    写一些有方法实现的接口,你不需要做任何特别的:

    
    interface Interface1 {
        fun function1() {
            Log.d("Interface1", "function1 called")
        }
    }
    
    

    我们有另外一个接口2实现了其他方法:

    
    interface Interface2 {
        fun function2() {
            Log.d("Interface2", "function2 called")
        }
    }
    
    

    有一个类都实现了他们没有问题:

    
    class MyClass : Interface1, Interface2 {
        fun myFunction() {
            function1()
            function2()
        }
    }
    

    好,当组织我们代码的时候,这给我们更多的多样性。

    接口不能持有状态

    这在思考代码时候有一个重要的限制。我们能有实现代码但是没有状态。这意味着我们不能创建一个属性,然后用它存储状态。如果我们在接口中定义了一个属性,这个类实现了它就必须重写这个属性。(你可以定义这个属性在接口中,但是实现类必须重写,本质是定义一个该属性的get方法)

    让我们看一个例子。想象一下这个接口需要上下文:

    
    interface Toaster {
        val context: Context
     
        fun toast(message: String) {
            Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
        }
    }
    

    这个代码很简单。这个接口有一个实现的方法用来显示一个Toast。 它需要一个上下文来做这些事情。如果我们有一个Activity要用这个接口,需要重写这个上下文:

    
    class MyActivity : AppCompatActivity(), Toaster {
        override val context = this
     
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            toast("onCreate")
        }
    }
    

    简单的,我们设置这个Activity 自己作为上下文,这个接口就使用它。 现在你可以在这个Activity 使用Toaster 函数没有任何问题。

    接口委托

    在Kotlin中另外的非常有趣的特性是接口委托。这个是非常强大的工具让你能实现一个更干净的代码组合。想象你有一个类C,组合了类A和B的2个对象:

    
    interface A {
        fun functionA(){}
    }
     
    interface B {
        fun functionB(){}
    }
     
    class C(val a: A, val b: B) {
        fun functionC(){
            a.functionA()
            b.functionB()
        }
    }
    

    类C在自己代码中使用A和B的函数。如果一个对象是组合自它们的组件,那它就可以直接的使用它们的函数。
    使用接口委托是另外一种写法,结果和上面一样的方式:

    
    class C(a: A, b: B): A by a, B by b {
        fun functionC(){
            functionA()
            functionB()
        }
    }
    
    

    你能看到类C实现了A和B,但是它接受作为参数,对象全部委托实现(个人理解是一个继承转化为组合的方式)。使用接口委托,这个类能直接使用被实现类的函数,并且包括使用其他对象委托实现。

    总结

    我们看到了Java和Kotlin接口的不同之处。现在试着找出简单的解决方式,这些新的方式打开了许多世界的可能。你们的代码会比之前有更多的复用性,以及更好的可读性。

    相关文章

      网友评论

          本文标题:Kotlin中的接口,谁说接口不能有实现代码

          本文链接:https://www.haomeiwen.com/subject/frgkixtx.html