why can't interfaces inherit from classes ?
# announcements
l
why can't interfaces inherit from classes ?
e
that's how Java's object model works. single-inheritance for classes, to avoid diamond MRO. mutiple-inheritance for interfaces, there's no behavior so there's no MRO issues.
... somewhat violated by the interfaces with default implementations, but that's a later addition (in both Java and Kotlin)
l
i dont quite see how an interface inheriting from a class could cause a diamong problem as long as the interface cannot override the class's behavior
e
Copy code
class A {
    fun foo() = 1
}
class B {
    fun foo() = 2
}
interface C : A
interface D : B
class E : C, D
l
in that example E ends up inheriting from 2 classes, which is illegal
e
but multi-inheritance for interfaces is legal
l
so what ?
e
so to prevent multi-inheritance of classes, interfaces can't be allowed to extend classes
l
that conclusion doesnt necessarily follow. the compiler could just check if the hierachy contains multiple base classes and throw an error if it does
r
It does check, that's the point of separating interfaces and classes.
e
Java (and Kotlin) is designed for separate compilation
you can't check the whole hierarchy, it may not be available at compile time or it may be different at runtime
l
oh you can't ? guess i'll have to take your word on that one cuz im not familiar enough with compilation
r
It doesn't make sense to have an interface inherit from a class. That's not what interface means.
l
that's circular reasoning
e
it means what it means so that the language works
r
No, it's not. It's precisely why they are called interfaces.
They define an interface for components to use. They aren't the components themselves.
l
well you could apply the same argument to default implementations
e
no, because those are subject to other restrictions
it's not like there aren't other ways around the issue - Scala's self-type, for example - but they're not safely compatible with Java
r
Indeed, there are plenty of other ways to solve the problem. Traits are a common implementation in other languages. However, they will also have their limitations based on their purpose.
It's good to keep in mind that many of these limitations aren't necessarily technical, but are semantic. The purpose is to make reasoning about the program easier for our wetware, not for the computer's hardware.
e
that being said, as far as the JVM is concerned... interfaces cannot extend classes for technical reasons as well. there is no way to invoke the constructor during object initialization
i
Curiously, when interfaces were called traits in Kotlin before 1.0, they were allowed to define a base class constraint, so that an implementing class must have inherited from that base class. An example of what it looked like: https://stackoverflow.com/questions/28298152/kotlin-superclass-is-not-accessible-from-trait
106 Views