为什么Kotlin`Any`是类而不是接口?
KotlinAny是一个类,其方法来自Java为什么Kotlin`Any`是类而不是接口?,kotlin,Kotlin,KotlinAny是一个类,其方法来自JavaObject open class Any() { open operator fun equals(other: kotlin.Any?): kotlin.Boolean { /* compiled code */ } open fun hashCode(): kotlin.Int { /* compiled code */ } open fun toString(): kotlin.String { /* compiled
Object
open class Any() {
open operator fun equals(other: kotlin.Any?): kotlin.Boolean { /* compiled code */ }
open fun hashCode(): kotlin.Int { /* compiled code */ }
open fun toString(): kotlin.String { /* compiled code */ }
}
为什么会这样
我会预测,由于原语被认为是
Any
,但实际上不是对象
,所以最好让Any
有一个他们假装实现的接口,而不是假装继承的类。对象
在Kotlin中不存在。这是一个Java概念。编译后,字节码与Java类型(如Object
)兼容,这一事实从Kotlin语言的角度来看是不相关的
Nat Pryce写了一篇非常简短、可读性很强的文章来解释Kotlin类型的系统
在信中你会注意到他说:
Any相当于Java的对象类
但它们不是一回事。Java和Kotlin类型的系统是完全独立的
Any
不是接口,因为它与Java的对象的作用几乎相同。在Kotlin中,Any?
是包含可在类型系统中表示的所有类型的类型。而Any
是包含除null
值以外的所有类型的类型。所以实际上,Any?
是Kotlin的对象。它是一种类型,其原因与对象
是一种类型相同
正如其他人提到的,Kotlin的类型系统中没有原语,因此它们不需要继承或假装继承任何接口。它们不存在。如果有接口,但每个类和接口都隐式继承自它,那么它必须具有默认的equals
和hashcode
,这对接口来说没有概念意义
此外,由于每个接口都将从任何接口继承,因此当一个类从多个接口继承时,会发生冲突。将使用equals
和hashcode
的哪个超级类型实现?接口的多重继承是一种非常常见的情况,因此您将非常频繁地处理冲突接口函数签名的复杂性,而不是千载难逢。Hm,如果它们是接口,您介意在多重接口继承中处理冲突吗?我不认为存在冲突,您只继承您或您的超类型实现的所有接口集?您不能从多个类继承o。操作性实际上不是Any
。但Kotlin通过在用作Any
时自动将原语装箱到其对象形式来隐藏这一事实。没有人会假装它们不是什么,只是Kotlin编译器在可能的情况下使用primitiveint
,在需要的时候使用objectInteger
。Kotlin抽象出了原语和它们的包装器之间的差异。从高层次上讲,就语法而言,没有原语。您只需要在尝试优化时考虑区别。即使您确实将它们视为原语,原语拥有接口类型也没有类类型更有意义。另外,如果一个接口有equals
和hashcode
的默认实现,那就没有意义了。我同意你所说的。你还可以说为什么Any不是一个接口吗?更新了我的答案,使之更明确。我不太确定我是否理解你的观点。接口已经可以重写equals()
,因此您可以从不同的接口继承的任何方法。作为一个接口,Any
在这方面会有什么不同呢?而且,即使在Java中,接口方法的默认实现实际上也是受支持的。为什么没有意义呢?接口不能重写任何类似equals()
的函数。我想说的是,对于一个接口来说,使用equals或hashcode的默认实现在概念上是没有意义的。它们在逻辑上是可以的,但由于接口所代表的内容,不清楚其含义是什么。接口通常只是类定义的一部分equals
和hashcode
应该代表类的所有状态。@Tenour04你说得对。由于某种原因,我的IDE让我失望了。不过,我不明白为什么会有这样的人为限制。由于接口可以为其他方法提供实现,因此可能会出现多重继承的问题,通常情况下这是可以解决的。为什么任何都有特殊情况?啊,最后一个问题我有答案