Kotlin secundaire constructor

Hoe declareer ik een secundaire constructor in Kotlin?

Is daar documentatie over?

Het volgende compileert niet…

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

Antwoord 1, autoriteit 100%

Update: sinds M11 (0.11.*) ondersteunt Kotlin secundaire constructeurs.


Voor nu ondersteunt Kotlin alleen primaire constructors (secundaire constructors kunnen later worden ondersteund).

De meeste use-cases voor secundaire constructors worden opgelost met een van de onderstaande technieken:

Techniek 1.(lost je probleem op) Definieer een fabrieksmethode naast je klas

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

gebruik:

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

Techniek 2.(kan ook nuttig zijn) Definieer standaardwaarden voor parameters

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

gebruik:

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

Merk op dat standaardwaarden werken voor elke functie, niet alleen voor constructeurs

Techniek 3.(wanneer u inkapseling nodig heeft) Gebruik een fabrieksmethode die is gedefinieerd in een begeleidend object

Soms wilt u dat uw constructor privé is en dat alleen een fabrieksmethode beschikbaar is voor klanten. Voorlopig is dit alleen mogelijk met een fabrieksmethode gedefinieerd in een begeleidend object:

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

gebruik:

val c = C.new("foo")

Antwoord 2, autoriteit 44%

Als documentatiepuntenkun je op deze manier een secundaire constructor gebruiken

class GoogleMapsRestApiClient constructor(val baseUrl: String) {
    constructor() : this("https://api.whatever.com/")
}

Vergeet niet dat u het eerste constructorgedrag moet uitbreiden.


Antwoord 3, autoriteit 22%

gebruik voor het declareren van een secundaire constructor Kotlinhet trefwoord constructor: like

dit is een primaire constructor:

class Person constructor(firstName: String) {
}

of

class Person(firstName: String) {
}

voor de secundaire constructorcode als volgt:

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

het is verplicht om de primaire constructoraan te roepen, anders geeft de compilerde volgende fout

Primary constructor call expected

Antwoord 4, autoriteit 12%

Constructeurs met init:

class PhoneWatcher : TextWatcher {
    private val editText: EditText
    private val mask: String
    private var variable1: Boolean = false
    private var variable2: Boolean = false
    init {
        variable1 = false
        variable2 = false
    }
    constructor(editText: EditText) : this(editText, "##-###-###-####")
    constructor(editText: EditText, mask: String) {
        this.editText = editText
        this.mask = mask
    }
    ...
}

Antwoord 5, autoriteit 6%

Je kunt meerdere constructors in Kotlin definiëren met constructormaar je moet de standaard constructor class AuthLog(_data: String)

overslaan

class AuthLog {
    constructor(_data: String): this(_data, -1)
    constructor(_numberOfData: Int): this("From count ", _numberOfData)
    private constructor(_data: String, _numberOfData: Int)
}

Zie hier voor meer informatie

Bijwerken

Nu kunt u de standaardconstructor definiëren

class AuthLog(_data: String, _numberOfData: Int) {
    constructor(_data: String): this(_data, -1) {
        //TODO: Add some code here if you want
    }
    constructor(_numberOfData: Int): this("From count", _numberOfData)
}

Antwoord 6, autoriteit 6%

Te laat om te antwoorden, maar hier is mijn bescheiden bijdrage 🙂

Omdat Kotlin de standaard parameterwaarde ondersteunt, (let op: ik wil power of null gebruiken) als volgt:

data class MyClass(val a: Int? = null, val b: String? = null, val c: Double? = null)

we hoeven niet meerdere constructors te hebben. maar zelfs als we het willen, kunnen we het ook op deze manier doen:

data class MyClass(val a: Int?, val b: String?, val c: Double?){
    constructor() : this(null,null,null)
    constructor(a : Int) : this(a,null,null)
    constructor(a : Int, b: String) : this(a,b,null)
}

we kunnen deze klasse op de volgende manieren instantiëren:

println(MyClass().toString())
println(MyClass(1).toString())
println(MyClass(1,"String").toString())
println(MyClass(1,"String",0.5).toString())

en laten we ook het resultaat zien:

voer hier de afbeeldingsbeschrijving in


Antwoord 7, autoriteit 6%

Voorbeeld van aangepaste weergave met meerdere constructors in Android:

class ShaderBackground : View {
    constructor(context: Context) : super(context) {
        init()
    }
    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
        init()
    }
    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        init()
    }
    private fun init() {
       // Init stuff here
        paint = Paint();
        paint.strokeWidth = 10f;
        paint.style = Paint.Style.FILL_AND_STROKE;
    }

Antwoord 8, autoriteit 4%

Ik zag deze vraag net en ik denk dat er misschien een andere techniek is die zelfs beter klinkt dan die van Andrey.

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

Dat je iets als val c:C = C(3)of val c:C = C("abc")kunt schrijven, omdat de invoke-methoden werken ongeveer op dezelfde manier als de apply-methoden in Scala.

Bijwerken

Vanaf nu maken secundaire constructors al deel uit van de taalspecificatie, dus deze tijdelijke oplossing mag niet worden gebruikt.


Antwoord 9, autoriteit 2%

Het onderstaande codefragment zou moeten werken

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

Antwoord 10

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

u kunt dit proberen.


Antwoord 11

Ik was een beetje in de war met de meeste antwoorden.
Om het gemakkelijk te begrijpen te maken, voeg ik een voorbeeld toe met meer elementen:

  @JsonInclude(JsonInclude.Include.NON_NULL)
   data class Response(val code: String) {
      var description: String? = null
      var value: String? = null
      constructor(code: String, description: String?) : this(code) {
          this.description = description
      }
      constructor(code: String, description: String?, value: String) : this(code, description) {
          this.value = value
      }
   }

Antwoord 12

kotlin Voorbeeld secundaire constructor

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")
    }
}

hoofdfunctie

fun main(args : Array<String>){
    var objd=Person(25,"Deven")
    objd.display()
}

Antwoord 13

Gebruik de variabele ‘internal’ en dan kun je meerdere constructors binnen een enkele klasse toevoegen, zoals hieronder. Dit zal feilloos werken.

class AuthModel {
var code: String? = null
internal constructor(code: String?) {
    this.code = code
}
internal constructor() {}
}

Other episodes