2013-10-10 7 views
51

Как объявить вторичный конструктор в Котлине?Вторичный конструктор Kotlin

Есть ли документация об этом?

После не компилируется ...

class C(a : Int) { 
    // Secondary constructor 
    this(s : String) : this(s.length) { ... } 
} 

ответ

61

Update: С M11 (. * 0,11) Котлин поддерживает secondary constructors.


На данный момент Kotlin поддерживает только первичные конструкторы (вспомогательные конструкторы могут поддерживаться позже).

В большинстве случаев используют для вторичных конструкторов решаемых одной из следующих методик:

Методики 1. (решает ваш случай) Определить метод фабрики рядом с классом

fun C(s: String) = C(s.length) 
class C(a: Int) { ... } 

использование:

val c1 = C(1) // constructor 
val c2 = C("str") // factory method 

Методика 2. (также может быть полезным) Defin е значения по умолчанию для параметров

class C(name: String? = null) {...} 

использование:

val c1 = C("foo") // parameter passed explicitly 
val c2 = C() // default value used 

Обратите внимание, что значения по умолчанию работы для любой функции, а не только для конструкторов

Техника 3. (когда вам нужна инкапсуляция) Использовать заводской метод, определенный в сопутствующем объекте

So вы хотите, чтобы ваш конструктор был закрыт и только клиентский метод фабрики. На данный момент это возможно только с заводским способом, определенный в компаньон объекта:

class C private (s: Int) { 
    companion object { 
     fun new(s: String) = C(s.length) 
    } 
} 

использование:

val c = C.new("foo") 
+8

Если вторичные конструкторы никогда не поддерживаются, первичные Конструкторы должны быть переименованы. ;) – Scooter

+2

Андрей Бреслав, я считаю, что было плохой идеей отказаться от поддержки вторичных конструкторов в Котлине, поскольку эти конструкторы необходимы иногда, особенно при работе с фреймворками Java и расширении Java-классов. Надеюсь, вы скоро их получите. – Michael

+0

Это смешно: вторичные конструкторы вернулись обратно :) – ruX

4

Я только что видел этот вопрос, и я думаю, что может быть другая техника, которая звучит даже чем те, которые предложил Андрей.

class C(a: Int) { 
    class object { 
     fun invoke(name: String) = C(name.length) 
    }   
} 

Что вы можете либо написать что-то вроде val c:C = C(3) или val c:C = C("abc"), потому что invoke методы работают такие же образом apply методы работы в Scala.

Update

В настоящее время, вторичные Конструкторы уже являются частью языка спецификации, так этот способ не следует использовать.

+0

Дополнительные конструкторы (с M11) лучше, чем этот вариант. –

+0

Я ответил на это до выпуска M11, это довольно просто, чтобы уменьшить его, почему бы вам просто не попробовать отредактировать ответ? – caeus

+0

Я не могу отредактировать ответ, потому что мое редактирование не будет соответствовать вашему ответу.Я не согласен с тем, что это вообще должно быть предложено. Удаление вашего ответа предотвратит мой downvote. –

7

Как documentation points, вы можете использовать вторичный конструктору таким образом

class GoogleMapsRestApiClient constructor(val baseUrl: String) { 

    constructor() : this("https://api.whatever.com/") 

} 

Помните, что вы должны расширить первое поведение конструктора.

+1

Вместо того, чтобы расширять первый конструктор непосредственно со второго, можно делегировать другому вторичному конструктору, который уже делает это: – Picrochole

+0

Я думаю, что это должен быть принятый ответ –

+0

Я думаю это один лучше для текущего случая: ' класс GoogleMapsRestApiClient конструктор (значение BaseUrl: String = "https://api.whatever.com/") { // тело класса } ' –

1
class Person(val name: String) { 
    constructor(name: String, parent: Person) : this(name) { 
     parent.children.add(this) 
    } 
} 

вы можете попробовать это.

1

фрагмент кода ниже, должны работать

class C(a:Int){ 
    constructor(s:String):this(s.length){..} 
} 
6

для объявления вторичный конструктор Котлин просто использовать конструктор ключевое слово: как

это является основным конструктором

class Person constructor(firstName: String) { 

} 

или

class Person(firstName: String) { 

} 

для вторичного конструктора кода:

class Person(val name: String) { 
    constructor(name: String, parent: Person) : this(name) { 
     parent.children.add(this) 
    } 
} 

это является обязательным для вызова основного конструктора иначе компилятор выбросит следующей ошибки

Primary constructor call expected 
0

kotlin Пример вспомогательного конструктора

class Person(name: String){ 
    var name="" 
    var age=0 

    constructor(age :Int,name : String) : this(name){ 
     this.age=age 
     this.name=name 
    } 
    fun display(){ 
     print("Kotlin Secondary constructor $name , $age") 
    } 
} 

Основная функция

fun main(args : Array<String>){ 

    var objd=Person(25,"Deven") 
    objd.display() 
} 
Смежные вопросы