Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Kotlin modifier 'open' is incompatible with 'data'?

I have a class:

open data class Person(var name: String)

and another class:

data class Student(var reg: String) : Person("")

this gives me an error that:

error: modifier 'open' is incompatible with 'data'

if I remove data from Person class it's fine.

why kotlin open and data incompatible?

like image 525
Arbaz Mateen Avatar asked May 30 '17 15:05

Arbaz Mateen


2 Answers

From https://kotlinlang.org/docs/reference/data-classes.html:

To ensure consistency and meaningful behavior of the generated code, data classes have to fulfil the following requirements:

  • The primary constructor needs to have at least one parameter;
  • All primary constructor parameters need to be marked as val or var;
  • Data classes cannot be abstract, open, sealed or inner;
  • (before 1.1) Data classes may only implement interfaces.

So the main point is that data class has some generated code (equals, hashCode, copy, toString, componentN functions). And such code must not be broken by the programmer. As a result, data class has some restrictions.

like image 87
Anton Holovin Avatar answered Oct 27 '22 18:10

Anton Holovin


As the documentation states,

  • Data classes cannot be abstract, open, sealed or inner;

The reason why they cannot be inherited is that inheriting from a data class causes an ambiguity with how their generated methods (equals, hashcode, etc.) should work. See further discussion about this in an answer to another question.

Since Kotlin 1.1, the restrictions on data classes have been lifted slightly: They can now inherit from other classes, as described in detail in the related proposal. However, they still cannot be inherited from themselves.


Note that data classes “only” provide the extra convenience of the automatic equals, hashcode, toString, component, and copy functions. If you don’t need those, then a class like the following still has properties with getters/setters and a constructor in a very brief form, and has no limitations on how you can use it with inheritance:

class User(val name: String, var age: Int)
like image 17
zsmb13 Avatar answered Oct 27 '22 16:10

zsmb13