Initialisatorer i hurtig del 1: (intro, bekvemmelighed og udpegede intializers)

Initialisering er et kæmpe emne, der skal dækkes hurtigt. Jeg vil prøve at forenkle det så meget som jeg kan i denne artikel.

https://stocksnap.io/
Apple-dokumenter: Initialisering er processen med at forberede en instans af en klasse, struktur eller optælling til brug. Denne proces involverer indstilling af en startværdi for hver gemt egenskab i den pågældende instans og udførelse af enhver anden opsætning eller initialisering, der er påkrævet, før den nye instans er klar til brug.

Klasser og strukturer skal indstille alle deres lagrede egenskaber til en passende startværdi på det tidspunkt, hvor en instans af den klasse eller struktur oprettes. Gemte egenskaber kan ikke efterlades i ubestemt tilstand.

startværdier

Initialisatorer er som specielle metoder, der kan kaldes for at oprette en ny forekomst af en bestemt type.

I sin enkleste form er en initializer ligesom en instansmetode uden parametre skrevet ved hjælp af init-nøgleordet:

i det() {
// udfør noget initialisering her
}

Som jeg har nævnt før, kan lagrede egenskaber ikke efterlades i ubestemt tilstand. Nogle værdier skal tildeles dem på tidspunktet for indvielsen. Overvej følgende klasse:

enum Køn {
sag han
sag kvindelig
sag ukendt
}
struktur Human {
var køn: Køn // Dette er en gemt egenskab.
init (køn: Køn) {
self.gender = køn
}
}
lad menneske = menneske (køn: .male)

Her tildeler jeg en vis værdi til det variable køn på tidspunktet for initialisering inde i initialiseringen. Hvis du ikke bruger init-metoden til at tildele variablen køn en vis værdi, skal du gøre et af følgende:

  • Du skal enten indstille variablen til en standardværdi på erklæringstidspunktet.
var køn: Køn = .male
  • Eller bør du erklære variablen som valgfri.
var køn: Køn?

Målet er, at alle egenskaber skal initialiseres på tidspunktet for initialisering af et eksempel.

Tilpasning af initialisering

Vi kan tilføje tilpassede initialisatorer til en klasse med tilpassede inputparametre og valgfri egenskabstyper.

Vi kan have mere end en initialisator baseret på vores krav med forskellige parameternavne, typer osv.
struktur Human {
var køn: Køn
var alder: Int = 10
init (køn: Køn) {// initialisering 1
self.gender = køn
}
init (alder: Int) {// initialisering 2
self.age = alder
self.gender =. ukendt
}
init (alder: Int, køn: Køn) {// initialisering 3
self.age = alder
self.gender = køn
}
}
// ------------------------------
lad menneske = menneske (køn: .male)
lad human2 = menneske (alder: 20)
lad human3 = menneske (alder: 40, køn: .male)
Den hurtige kompilator bestemmer, hvilken init-metode der skal kaldes på baggrund af argumentetiketten.

Bemærk, at det ikke er muligt at kalde disse initialisatorer uden at bruge argumentetiketter. Argumentetiketter skal altid bruges i en initializer, hvis de er defineret, og at udelade dem er en kompileringstid-fejl:

lad human4 = Human () // error: kan ikke påberåbe initializer for typen 'Human' uden argumenter
lad human5 = Human (40, .male) // error: error: mangler argumentetiketter 'age: gender:' i opkald

Initialiseringsparametre uden argumenteretiketter

Hvis du ikke ønsker at bruge en argumentetiket til en initialiseringsparameter, skal du skrive en understregning (_) i stedet for en eksplicit argumentetiket for den parameter for at tilsidesætte standardadfærden.

Lad os nu tilføje en init-metode til den menneskelige klasse som denne:

init (_ alder: Int, _ køn: Køn) {
self.age = alder
self.gender = køn
}

Nu kan vi ringe til:

lad human5 = menneske (40, .male)

Standardinitieringsprogrammer

Swift leverer en standardinitialisator til enhver struktur eller klasse, der leverer standardværdier for alle dens egenskaber og ikke indeholder mindst en initializer selv. Standardinitialisatoren opretter simpelthen en ny instans med alle dens egenskaber indstillet til deres standardværdier.

Dette eksempel definerer en klasse kaldet ShoppingListItem, som indkapsler navn, mængde og købstilstand for en vare på en indkøbsliste:

klasse ShoppingListItem {
var navn: String?
var mængde = 1
var købt = falsk
}
var item = ShoppingListItem ()

Initialisatorer med medlemsvise for strukturtyper

Strukturtyper modtager automatisk en medlemsvis initialisator, hvis de ikke definerer nogen af ​​deres egne brugerdefinerede initialisatorer.

Bemærk:

  • Hvis vi ikke leverer en brugerdefineret initializer, modtager strukturen en initialiseret initialisering, selvom den har gemte egenskaber, der ikke har standardværdier.
  • Hvis vi ikke leverer en brugerdefineret initialisering, modtager strukturen en initialiseret initialisering, selvom den har gemte egenskaber, der har standardværdier.

Overvej en struktur kaldet størrelse

struktur Størrelse {
var bredde, højde: Dobbelt // lagrede egenskaber uden standardværdier
}
-------- eller --------------
struktur Størrelse {
var bredde = 10,0, højde = 30,0 // lagrede egenskaber med standardværdier
}

Den første struktur har to lagrede egenskaber uden standardværdier. Den anden struktur har to lagrede egenskaber med angivne standardværdier. Tilpassede initialisatorer er ikke givet i begge tilfælde. For at initialisere denne struktur får vi en medlemsvis initializer med bredde og højde som parametre:

lad twoByTwo = størrelse (bredde: 2,0, højde: 2,0)
Hvis vi leverer en tilpasset init-metode, skal alle de lagrede egenskaber initialiseres som forklaret tidligere i denne artikel. Initialiseringen med medlemsvisningen er heller ikke tilgængelig i dette tilfælde. ie; Hvis du definerer en brugerdefineret initialisering for en værditype, har du ikke længere adgang til standardinitieringsprogrammet (eller medlemsvise initialisator, hvis det er en struktur) for den type.
struktur Størrelse {
var bredde, højde: dobbelt
i det(){
selvbredde = 10,0
selvhøjde = 30,0
}
}
lad størrelseObj1 = Størrelse (bredde: 2,0, højde: 2,0) // fejl. argument overført til opkald, der ikke tager nogen argumenter
let sizeObj2 = Størrelse () // succes.

Initialiseringsdelegation for værdityper

Initialisatorer kan ringe til andre initialisatorer for at udføre en del af en instanss initialisering. Denne proces, kendt som initialiseringsdelegering.

  • Værdityper (strukturer og opregninger) understøtter ikke arv, og derfor er deres initialiseringsdelegationsproces relativt enkel, fordi de kun kan delegere til en anden initializer, som de leverer selv.
  • Klasser kan arve fra andre klasser som beskrevet i arv. Dette betyder, at klasser har yderligere ansvar for at sikre, at alle lagrede egenskaber, de arver, tildeles en passende værdi under initialisering.

Eksempel:

Følgende eksempel definerer en brugerdefineret Rect-struktur til at repræsentere et geometrisk rektangel. Eksemplet kræver to understøttende strukturer kaldet størrelse og punkt, som begge giver standardværdier på 0,0 for alle deres egenskaber:

struktur Størrelse {
var bredde = 0,0, højde = 0,0
}
struktur Punkt {
var x = 0,0, y = 0,0
}

Du kan initialisere Rect-strukturen nedenfor på en af ​​tre måder - ved at bruge dens standardværdier for nul-initialiseret oprindelses- og størrelsesegenskaber, ved at angive et specifikt oprindelsespunkt og -størrelse eller ved at angive et specifikt centerpunkt og -størrelse. Disse initialiseringsmuligheder er repræsenteret af tre brugerdefinerede initialiseringer, der er en del af Rectstructure's definition:

struktur Rect {
var oprindelse = Punkt ()
var størrelse = størrelse ()
i det() {}
init (oprindelse: Punkt, størrelse: Størrelse) {
self.origin = oprindelse
self.size = størrelse
}
init (center: Punkt, størrelse: Størrelse) {
lad originX = center.x - (størrelse.width / 2)
lad oprindelseY = center.y - (størrelse.højde / 2)
self.init (oprindelse: Point (x: originX, y: originY), størrelse: størrelse)
}
}

Udpegede initialisatorer og bekvemmelighedsinitieringsapparater

Alle klassens lagrede egenskaber - inklusive alle egenskaber, som klassen arver fra sin superklasse - skal tildeles en initial værdi under initialiseringen.

Swift definerer to slags initialisatorer for klassetyper for at sikre, at alle lagrede egenskaber får en startværdi.

  • Udpegede initialisatorer
  • Bekvemmelighedsinitialisatorer

Udpegede initialisatorer er de primære initialisatorer for en klasse. En udpeget initialisator initialiserer fuldt ud alle egenskaber, der er introduceret af den klasse, og kalder en passende superklasseinitialisator for at fortsætte initialiseringsprocessen op i superklassekæden.

Hver klasse skal have mindst en udpeget initializer.

Udpegede initialisatorer til klasser er skrevet på samme måde som enkle initialisatorer for værdityper:

init (_parametre, hvis nogen_) {
}

Bekvemmelighedsinitialisatorer er sekundære, understøttende initialiseringer for en klasse. Du kan definere en bekvemmelighedsinitialisator for at kalde en udpeget initializer fra samme klasse som bekvemmelighedsinitialisereren med nogle af de udpegede initialiseringsparametre indstillet til standardværdier. Du kan også definere en bekvemmelighedsinitializer til at oprette en forekomst af den klasse til en bestemt brugssag eller inputværditype.

Du behøver ikke at give bekvemmelighedsinitialisatorer, hvis din klasse ikke kræver dem. Opret bekvemmelighedsinitialisatorer, hver gang en genvej til et fælles initialiseringsmønster sparer tid eller gør initialisering af klassen klarere med vilje.

Bekvemmelighedsinitialisatorer er skrevet i samme stil, men med den komfortmodifikator, der er placeret før init-nøgleordet, adskilt med et mellemrum:

bekvemmelighedsinit (_parametre, hvis nogen_) {
}

Lad os se et eksempel: Klassemennesket har en udpeget init-metode og en bekvemmelighedsinit-metode.

klasse HumanBeing {
var navn: String
init (navn: String) {
self.name = navn
}
bekvemmelighed init () {
self.init (navn: “ikke sat”)
// Convenience init kalder den angivne init-metode
}
}
let humanBeingObj1 = HumanBeing () // kalder bekvemmelighed init
lad humanBeingObj2 = HumanBeing (navn: “abhilash”) // kaldes init
Convenience init initialiserer den udpegede init-metode ved at kalde self.init.

Initialiseringsdelegation for klassetyper

For at forenkle forholdet mellem udpegede og bekvemmelighedsinitieringsprogrammer anvender Swift følgende tre regler for delegationsopkald mellem initialiseringsprogrammer:

  • En udpeget initializer skal kalde en udpeget initialisator fra sin øjeblikkelige superklasse. En udpeget initializer af en underklasse kan ikke kalde en Convenience init fra dens superklasse. Hvis du prøver at gøre det, får du en fejl, der siger “fejl: skal kalde en udpeget initialisering af superklassen”.
  • En bekvemmelighedsinitialisator skal kalde en anden initializer fra samme klasse.
  • En bekvemmelighedsinitialisator skal i sidste ende ringe til en udpeget initializer.

Se på følgende billede, så det bliver mere tydeligt:

kilde: apple docs

Automatisk initiering af arv

Underklasser arver ikke deres superklasseinitialisatorer som standard. Dog superklasses initialiseringer arves automatisk, hvis visse betingelser er opfyldt.

Hvis vi leverer standardværdier for nye egenskaber, du introducerer i en underklasse, gælder følgende to regler:

  • Regel 1: Hvis din underklasse ikke definerer nogen udpegede initialisatorer, arver den automatisk alle dens superklasse-udpegede initialisatorer.
  • Regel 2: Hvis din underklasse giver en implementering af alle dens superklasse-udpegede initialisatorer - enten ved at arve dem som pr. Regel 1, eller ved at tilvejebringe en brugerdefineret implementering som en del af dens definition - arver den automatisk alle superclass-bekvemmelighedsinitialisatorer.

Overvej følgende eksempel og de tilgængelige initmetoder til at oprette et Man-klasse-objekt.

klasse HumanBeing {
var navn: String
init (navn: String) {
self.name = navn
}
bekvemmelighed init () {
self.init (navn: “ikke sat”)
// Convenience init kalder den angivne init-metode
}
}
let humanBeingObj1 = HumanBeing () // kalder bekvemmelighed init
lad humanBeingObj2 = HumanBeing (navn: “abhilash”) // opkald
udpeget init
____________________
klasse Mand: HumanBeing {
var alder: Int = 0
tilsidesætte init (navn: String) {
super.init (navn: navn)
}
init (navn: String, alder: Int) {
super.init (navn: navn)
self.name = navn
self.age = alder
}
}
_______________________
let manObj1 = Mand () // kalder bekvemmelighedsinit for menneskelig klasse
let manObj2 = Mand (navn: “Robert”) // opkald overstyres init
let manObj3 = Mand (navn: “John”, alder: 10) // kalder brugerdefineret init
manObj1.name // udskriver “ikke indstillet”
manObj2.name // udskriver “Robert”
manObj3.name // udskriver “John”

Hvor man skal hen herfra:

Initialisering i hurtig del-2: Tilgængelig initialisering i hurtig

Hvis du nød at læse dette indlæg og fandt det nyttigt, skal du dele og anbefale det, så andre kan finde det !!!!

Tak!!