kotlin授权有多大用处?

kotlin授权有多大用处?,kotlin,Kotlin,我真的对科特林代表团感到困惑。让我在这里描述一下规则多态性方法,它看起来与kotlin deligation相同 interface Base { fun print() } class BaseImpl(val x: Int) : Base { override fun print() { print(x) } } fun main(args: Array<String>) { val b : Base = BaseImpl(10) b.print(

我真的对科特林代表团感到困惑。让我在这里描述一下规则多态性方法,它看起来与kotlin deligation相同

interface Base {
    fun print()
}
class BaseImpl(val x: Int) : Base {
    override fun print() { print(x) }
}
fun main(args: Array<String>) {
    val b : Base = BaseImpl(10)
    b.print() // prints 10
}

我知道这是一个简单的场景,两个代码都运行良好。应该有授权的好处,这就是为什么kotlin引入了它。有什么区别?科特林授权如何发挥作用?请给我一个与多态性方法进行比较的工作示例。

这很有用,因为大多数行为都可以与委托的目标相同(
b
),但您只想覆盖方法的子集以采取不同的行动

例如,
InputStream
实现将所有工作委托给另一个
InputStream
,但覆盖
close()
方法以不关闭底层流。这可以通过以下方式实施:

class CloseGuardInputStream(private val base: InputStream)
    : InputStream by base {
    override fun close() {}
}

它对于创建装饰器和对象组合非常有用。 Joshua Bloch在《有效Java》第二版第16项“偏好组合而非继承”中展示了一个很好的例子:继承很容易被破坏,而装饰器则不容易

继承:

class LoggingList<E> : ArrayList<E>() {

    override fun add(e: E): Boolean {
        println("added $e")
        return super.add(e)
    }

    override fun addAll(e: Collection<E>): Boolean {
        println("added all: $e")
        return super.addAll(e) // oops! Calls [add] internally.
    }

}
类日志列表:ArrayList(){
覆盖乐趣添加(e:e):布尔值{
println(“添加$e”)
返回super.add(e)
}
覆盖乐趣添加全部(e:集合):布尔值{
println(“全部添加:$e”)
返回super.addAll(e)//oops!内部调用[add]。
}
}
代表团:

class LoggingList<E>(delegate: MutableList<E>) : MutableList<E> by delegate {

    override fun add(e: E): Boolean {
        println("added $e")
        return delegate.add(e)
    }

    override fun addAll(e: Collection<E>): Boolean {
        println("added all: $e")
        return delegate.addAll(e) // all OK
        // it calls [delegate]'s [add] internally, not ours
    }

}
类日志列表(委托:可变列表):按委托列出可变列表{
覆盖乐趣添加(e:e):布尔值{
println(“添加$e”)
返回委托。添加(e)
}
覆盖乐趣添加全部(e:集合):布尔值{
println(“全部添加:$e”)
返回delegate.addAll(e)//all OK
//它在内部调用[delegate]的[add],而不是我们的[add]
}
}

还请记住,您不限于一个代理。Kotlin实现委托的方式类似于Groovy等语言中的
traits
实现。您可以通过委托组合不同的功能。Kotlin的方法也可以被认为更强大,因为您也可以“插入”不同的实现

interface Marks {
  fun printMarks()
}

class StdMarks() : Marks {
  override fun printMarks() { println("printed marks") }
}

class CsvMarks() : Marks {
  override fun printMarks() { println("printed csv marks") }
}

interface Totals {
  fun printTotals()
}

class StdTotals : Totals {
  override fun printTotals() { println("calculated and printed totals") }
}

class CheatTotals : Totals {
  override fun printTotals() { println("calculated and printed higher totals") }
}

class Student(val studentId: Int, marks: Marks, totals: Totals) 
  : Marks by marks, Totals by totals

fun main(args:Array<String>) {
  val student = Student(1,StdMarks(), StdTotals())
  student.printMarks()
  student.printTotals()
  val cheater = Student(1,CsvMarks(), CheatTotals())
  cheater.printMarks()
  cheater.printTotals()
}

继承不能这样做。

以下是示例:-

现在,自定义模式可以重用两种模式的
display()
功能
DarkMode
&
LightMode

fun main() {
MyCustomMode(DarkMode("CUSTOM_DARK_GRAY")).display()
MyCustomMode(LightMode("CUSTOM_LIGHT_GRAY")).display()
}

 /* output:
 Dark Mode...CUSTOM_DARK_GRAY
 Light Mode...CUSTOM_LIGHT_GRAY
*/
Kotlin本机支持委托模式。 Kotlin提供by关键字来指定自定义模式将要委托给的委托对象。 我们可以使用by关键字实现与上面代码相同的结果

class MyCustomMode(val mode: Mode): Mode by mode
fun main() {
MyCustomMode(DarkMode("CUSTOM_DARK_GRAY")).display()
MyCustomMode(LightMode("CUSTOM_LIGHT_GRAY")).display()
}

/* output:
Dark Mode...CUSTOM_DARK_GRAY
  Light Mode...CUSTOM_LIGHT_GRAY
 */

你能举个例子吗?所以我可以用接口多态性的方式来比较这个例子。我知道委派是有用的,但是kotlin的委派如何呢?你能在main方法中调用上面的代码吗。所以我可以和接口多态性示例进行比较?这个示例实际上不起作用,因为InputStream是一个类而不是一个接口。Kotlin中的委托仅通过接口支持。我仍然可以在没有`:MutableList by delegate`的情况下在内部调用。您能给我一个工作示例吗?因此,我可以与多态性方法进行比较。我认为您应该详细说明您的示例,这样您就可以证明这是如何像您所说的“非常有用”的。恐怕它不像你所说的那么明显。首先,这是一个有效的示例,只需将它复制并粘贴到try.kotlinlang.org并试用一下。第二:Miha的意思是,
addAll
对每个新项目内部调用
add
。因此,在继承示例中,每个项都将得到“added all”,然后是“added xy”,因为我们覆盖了
add()
。在委派示例中,您只会得到“added all”,因为addAll不调用我们的
add
,而是调用mutableList的
add
。我想知道这是一个关于委派本身优点的问题,而不是关于Kotlin如何实现它的问题。我问它Kotlin委派如何有用?这并不是代表团的作用。因为我已经知道代表团的目的。但是kotlin的实现让我很困惑,第一块代码没有给出与第二块代码相同的结果。试着手工实现
派生的
,你会感觉到不同。你能写出简短的代码吗?因为我真的不知道哪一个例子可以区分它们。G或
interface Mode{
val color:String
fun display()
 }

class DarkMode(override val color:String) : Mode{    
override fun display(){
    println("Dark Mode..."+color)
}
 }
class LightMode(override val color:String) : Mode {
override fun display() { 
    println("Light Mode..."+color) 
}
}

class MyCustomMode(val mode: Mode): Mode{
override val color:String = mode.color
override fun display() { 
    mode.display()
}
}
fun main() {
MyCustomMode(DarkMode("CUSTOM_DARK_GRAY")).display()
MyCustomMode(LightMode("CUSTOM_LIGHT_GRAY")).display()
}

 /* output:
 Dark Mode...CUSTOM_DARK_GRAY
 Light Mode...CUSTOM_LIGHT_GRAY
*/
class MyCustomMode(val mode: Mode): Mode by mode
fun main() {
MyCustomMode(DarkMode("CUSTOM_DARK_GRAY")).display()
MyCustomMode(LightMode("CUSTOM_LIGHT_GRAY")).display()
}

/* output:
Dark Mode...CUSTOM_DARK_GRAY
  Light Mode...CUSTOM_LIGHT_GRAY
 */