kotlin授权有多大用处?
我真的对科特林代表团感到困惑。让我在这里描述一下规则多态性方法,它看起来与kotlin deligation相同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(
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
*/