/ SCALA, KOTLIN

Scala vs Kotlin: Multiple Inheritance and the Diamond problem

This is the 4th post in the Scala vs. Kotlin focus series.Other posts include:

  1. Scala vs Kotlin: Pimp my library
  2. Scala vs Kotlin: Operator overloading
  3. Scala vs Kotlin: inline and infix
  4. Scala vs Kotlin: Multiple Inheritance and the Diamond problem (this post)

Inheritance is one of the basic tenet of Object-Oriented Programming, along with encapsulation and polymorphism. Alongside simple inheritance, there is multiple inheritance:

Multiple inheritance is a feature of some object-oriented computer programming languages in which an object or class can inherit characteristics and features from more than one parent object or parent class. It is distinct from single inheritance, where an object or class may only inherit from one particular object or class.
— Wikipedia
https://en.wikipedia.org/wiki/Multiple_inheritance

C++ is famous for allowing multiple inheritance, and describing the diamond problem. It states that there’s an issue when a child class inherits from multiple classes that have the same method.

diamond problem

C++ has its own way of coping with the diamond problem. In order to avoid it, Java completely disallows multiple-inheritance. Let’s check how Scala and Kotlin fare.

Scala

Scala doesn’t allow for multiple inheritance per se, but allows to extends multiple traits.

Traits are used to share interfaces and fields between classes. They are similar to Java 8’s interfaces. Classes and objects can extend traits but traits cannot be instantiated and therefore have no parameters.
— Scala Documentation
http://docs.scala-lang.org/tutorials/tour/traits.html

The above diagram translates into the following code:

trait Openable {
  def open() { ... }
}

trait Window extends Openable {
  def open() { ... }
}

trait Door extends Openable {
  def open() { ... }
}

class WindowDoor extends Door with Window {
  ...
}

Scala resolves the diamond problem by defining one main super trait - whose code will be used, among all super traits. The main one is set with the extends keyword, while other are with with.

Hence, in the above example, WindowDoor.open() will by default use code from Door.open(). Of course, nothing prevents us from overriding the method.

Kotlin

As in Scala, Kotlin doesn’t allow to extend multiple super classes. Yet, interfaces can have concrete functions.

Interfaces in Kotlin are very similar to Java 8. They can contain declarations of abstract methods, as well as method implementations. What makes them different from abstract classes is that interfaces cannot store state.
— Kotlin Documentation
https://kotlinlang.org/docs/reference/interfaces.html

The following is the code above translated in Kotlin:

interface Openable {
    fun open() { ... }
}

interface Window : Openable {
    override fun open() { ... }
}

interface Door : Openable {
    override fun open() { ... }
}

class WindowDoor : Door, Window {
    override fun open() { ... }
}

Kotlin takes another path to solve the diamond problem: explicit overriding. The compiler detects diamond occurrences, and fires an error if a function is implemented by multiple parent classes. To fix this, the developer must explicitly code the desired behavior.

Conclusion

While Scala’s approach is more elegant, Kotlin’s is consistent with its philosophy: being explicit and readable before being concise.

Nicolas Fränkel

Nicolas Fränkel

Developer Advocate with 15+ years experience consulting for many different customers, in a wide range of contexts (such as telecoms, banking, insurances, large retail and public sector). Usually working on Java/Java EE and Spring technologies, but with focused interests like Rich Internet Applications, Testing, CI/CD and DevOps. Also double as a trainer and triples as a book author.

Read More
Scala vs Kotlin: Multiple Inheritance and the Diamond problem
Share this