W Kotlinie każda klasa może mieć jeden konstruktor pierwotny (podawany w deklaracji klasy) i wiele konstruktorów wtórnych (poprzez constructor).
private, protected, internal, public) można ukrywać lub ograniczać widoczność konstruktorów.Przykład z konstruktorem pierwotnym i wtórnym:
open class Person(val name: String) { constructor(name: String, age: Int) : this(name) { // konstruktor wtórny } } class Employee : Person { constructor(name: String) : super(name) // Wymagane jest jawne super }
Modyfikatory widoczności:
class Secret private constructor() { companion object { fun create() = Secret() } } val s = Secret.create() // Ok, a Secret() - błąd
Niuanse:
Czy w Kotlinie można dziedziczyć klasę i nie wywoływać jej pierwotnego konstruktora?
Odpowiedź: Nie. W Kotlinie w przypadku dziedziczenia zawsze musi zostać wywołany przynajmniej jeden konstruktor rodzica - czy to pierwotny, czy wtórny (poprzez super()).
Przykład:
open class A(val x: Int) class B: A // Błąd: wymaga jawnego wywołania konstruktora A
Historia
W zespole próbowano zabronić tworzenia obiektów klasy bezpośrednio i zrobili konstruktor prywatny. Zapomniano jednak zaimplementować metodę fabryczną. Doprowadziło to do niemożności przetestowania klasy bez refleksji i zablokowania CI.
Historia
Dziedziczyli klasę z obowiązkowymi parametrami w konstruktorze pierwotnym, ale nie przekazali ich przy deklaracji dziedziczącego. To wykryto dopiero na etapie kompilacji po długim debugowaniu.
Historia
Podczas korzystania z konstruktorów wtórnych zapomniano, że wszystkie muszą wywoływać pierwotny. W rezultacie obiekty były inicjowane bez potrzebnych parametrów, co doprowadziło do NullPointerException w czasie wykonywania.