Initializatori în partea rapidă 1: (introducere, comoditate și intializatoare desemnate)

Inițializarea este un subiect imens pe care să-l abordăm rapid. Voi încerca să-l simplific cât pot de mult în acest articol.

https://stocksnap.io/
Documente Apple: inițializarea este procesul de pregătire a unei instanțe a unei clase, structuri sau enumerații pentru utilizare. Acest proces presupune setarea unei valori inițiale pentru fiecare proprietate stocată pe acea instanță și efectuarea oricărei alte configurații sau inițializări necesare înainte ca noua instanță să fie gata de utilizare.

Clasele și structurile trebuie să stabilească toate proprietățile stocate la o valoare inițială corespunzătoare până la momentul creării unei instanțe a acelei clase sau structuri. Proprietățile stocate nu pot fi lăsate într-o stare nedeterminată.

initializatori

Initializatorii, sunt ca metode speciale care pot fi apelate la crearea unei noi instanțe de un anumit tip.

În forma sa cea mai simplă, un inițiator este ca o metodă de instanță fără parametri, scrisă folosind cuvântul cheie init:

init () {
// efectuați o oarecare inițializare aici
}

După cum am menționat anterior, proprietățile stocate nu pot fi lăsate într-o stare nedeterminată. Unele valori ar trebui să li se atribuie în momentul inițierii. Luați în considerare următoarea clasă:

enum Gender {
caz masculin
caz feminin
caz necunoscut
}
struct Human {
var sex: Sex // aceasta este o proprietate stocată.
init (sex: sex) {
self.gender = sex
}
}
let uman = Human (gen: .male)

Aici atribuesc o anumită valoare variabilei de sex în momentul inițializării în interiorul inițializatorului. Dacă nu utilizați metoda init pentru a atribui o valoare variabilă sexului, trebuie să faceți oricare dintre următoarele acțiuni:

  • ar trebui să setați variabila o valoare implicită la data declarației.
var sex: Sex = .male
  • Sau ar trebui să declarați variabila ca opțională.
var sex: Gen?

Obiectivul este ca, la inițializarea unei instanțe, toate proprietățile să fie inițializate.

Personalizarea inițializării

Putem adăuga inițializatori personalizați la o clasă cu parametri de intrare personalizați și tipuri de proprietăți opționale.

Putem avea mai mult de un inițiator pe baza cerinței noastre, cu diferite nume de parametri, tipuri etc.
struct Human {
var sex: Gen
vârsta var: Int = 10
init (gen: sex) {// inițializator 1
self.gender = sex
}
init (vârsta: Int) {// inițializator 2
self.age = varsta
self.gender =. necunoscut
}
init (vârstă: Int, sex: Gen) {// inițiator 3
self.age = varsta
self.gender = sex
}
}
// ------------------------------
let uman = Human (gen: .male)
let human2 = Human (vârsta: 20)
let human3 = Human (vârsta: 40 de ani, sex: .male)
Compilatorul rapid va decide ce metodă init să apeleze pe baza etichetei argumentului.

Rețineți că nu este posibil să apelați acești inițiator fără a utiliza etichete cu argumente. Etichetele de argumente trebuie utilizate întotdeauna într-un inițializator dacă sunt definite, iar omiterea acestora este o eroare de compilare:

let human4 = Human () // eroare: nu poate invoca inițializatorul pentru tipul „Human” fără argumente
let human5 = Human (40, .male) // eroare: eroare: lipsesc etichetele de argumente „vârstă: sex:” în apel

Parametrii inițializatorului fără etichete cu argumente

Dacă nu doriți să utilizați o etichetă de argument pentru un parametru inițializator, scrieți o subliniere (_) în loc de o etichetă argument explicită pentru parametrul respectiv pentru a trece peste comportamentul implicit.

Acum, să adăugăm o metodă init la clasa Human astfel:

init (_ vârstă: Int, _ sex: sex) {
self.age = varsta
self.gender = sex
}

Acum putem apela:

let human5 = Human (40, .male)

Initializatoare implicite

Swift oferă un inițializator implicit pentru orice structură sau clasă care furnizează valori implicite pentru toate proprietățile sale și nu furnizează cel puțin un inițializator în sine. Initializatorul implicit creaza pur si simplu o noua instanta cu toate proprietatile sale setate la valorile lor implicite.

Acest exemplu definește o clasă numită ShoppingListItem, care încapsulează numele, cantitatea și starea de cumpărare a unui articol dintr-o listă de cumpărături:

class ShoppingListItem {
nume var: șir?
cantitatea var = 1
var cumpărat = fals
}
var item = ShoppingListItem ()

Initializatoare pentru membrii tipurilor de structuri

Tipurile de structură primesc automat un inițiator inițial, dacă nu definesc oricare inițializatori personalizați.

Puncte de reținut:

  • Dacă nu furnizăm un inițializator personalizat, structura primește un inițiator inițial, chiar dacă are proprietăți stocate care nu au valori implicite.
  • Dacă nu furnizăm un inițializator personalizat, structura primește un inițiator inițial, chiar dacă are proprietăți stocate care au valori implicite.

Luați în considerare o structură numită Dimensiune

struct Dimensiune {
var lățime, înălțime: dublu // proprietăți stocate fără valori implicite
}
-------- sau --------------
struct Dimensiune {
var lățime = 10,0, înălțime = 30,0 // proprietăți stocate cu valori implicite
}

Prima structură are două proprietăți stocate fără valori implicite. A doua structură are două proprietăți stocate cu valorile implicite date. Initializatoarele personalizate nu sunt date în ambele cazuri. Pentru inițializarea acestei structuri, obținem un inițiator inițial, cu lățimea și înălțimea ca parametri:

let twoByTwo = Dimensiune (lățime: 2,0, înălțime: 2,0)
Dacă furnizăm o metodă de inițiere personalizată, toate proprietățile stocate ar trebui să fie inițializate, așa cum este explicat anterior în acest articol. De asemenea, inițializatorul pentru membri nu va fi accesibil în acest caz. și anume; dacă definiți un inițializator personalizat pentru un tip de valoare, nu veți mai avea acces la inițializatorul implicit (sau inițiator inițial, dacă este o structură) pentru acel tip.
struct Dimensiune {
var latime, inaltime: dublu
init () {
lățime de sine = 10,0
self.height = 30.0
}
}
let sizeObj1 = Dimensiune (lățime: 2,0, înălțime: 2,0) // eroare. argument transmis la apel care nu are argumente
let sizeObj2 = Size () // succes.

Initializator Delegatie pentru tipuri de valori

Initializatorii pot apela alți inițiatori pentru a efectua o parte din inițializarea unei instanțe. Acest proces, cunoscut sub numele de delegator inițiator.

  • Tipurile de valori (structuri și enumerari) nu acceptă moștenirea și, prin urmare, procesul lor de delegare a inițiatorului este relativ simplu, deoarece acestea pot delega doar la un alt inițiator pe care îl furnizează.
  • Clasele, pot moșteni de la alte clase, așa cum este descris în Moștenire. Aceasta înseamnă că clasele au responsabilități suplimentare pentru a se asigura că tuturor proprietăților stocate pe care le moștenesc li se atribuie o valoare adecvată în timpul inițializării.

Exemplu:

Următorul exemplu definește o structură Rect personalizată pentru a reprezenta un dreptunghi geometric. Exemplul necesită două structuri de sprijin numite Dimensiune și punct, ambele furnizând valori implicite de 0,0 pentru toate proprietățile lor:

struct Dimensiune {
lățimea var = 0,0, înălțimea = 0,0
}
struct Point {
var x = 0,0, y = 0,0
}

Puteți inițializa structura Rect de mai jos într-unul din cele trei moduri - folosind valorile sale inițial inițializate inițial și valorile proprietății, prin furnizarea unui punct și dimensiune specific de origine sau prin furnizarea unui punct și dimensiune specific. Aceste opțiuni de inițializare sunt reprezentate de trei inițializatori personalizați care fac parte din definiția Rectstructure:

struct Rect {
origine var = Punct ()
mărimea var = dimensiunea ()
init () {}
init (origine: Punct, mărime: Mărime) {
self.origin = origine
self.size = dimensiune
}
init (centru: Punct, mărime: Mărime) {
let originX = center.x - (size.width / 2)
let originY = center.y - (size.height / 2)
self.init (origine: Point (x: originX, y: originYY), mărime: mărime)
}
}

Initializatori desemnați și inițializatori convenabili

Toate proprietățile stocate ale unei clase - inclusiv orice proprietăți pe care le moștenește clasa de la superclasa sa - trebuie să li se atribuie o valoare inițială în timpul inițializării.

Swift definește două tipuri de inițializatoare pentru tipurile de clase pentru a vă asigura că toate proprietățile stocate primesc o valoare inițială.

  • Initializatori desemnați
  • Initializatori de comoditate

Initializatorii desemnați sunt inițiatorii primari pentru o clasă. Un inițiator desemnat inițializează complet toate proprietățile introduse de acea clasă și apelează la un inițializator de superclase adecvat pentru a continua procesul de inițializare în lanțul superclasei.

Fiecare clasă ar trebui să aibă cel puțin un inițializator desemnat.

Initializatorii desemnați pentru clase sunt scrise în același mod ca inițiatori simpli pentru tipuri de valori:

init (_parametri dacă este cazul) {
}

Initializatorii convenabili sunt secundari, sprijinind inițiatorii pentru o clasă. Puteți defini un inițiator de convenție pentru a apela un inițiator desemnat din aceeași clasă ca inițializatorul de comoditate, cu unii dintre parametrii inițiatorului desemnat stabiliți la valori implicite. Puteți defini, de asemenea, un inițializator de comoditate pentru a crea o instanță a acelei clase pentru un caz de utilizare specific sau un tip de valoare de intrare.

Nu trebuie să furnizați inițializatori de comoditate dacă clasa dvs. nu le solicită. Creați inițializatori de convenție ori de câte ori o comandă rapidă către un model comun de inițializare va economisi timp sau va face ca inițializarea clasei să fie mai clară în intenție.

Initializatorii de conveniență sunt scrise în același stil, dar cu modificatorul de comoditate plasat înaintea cuvântului cheie init, separat de un spațiu:

init initia (_parametri daca este cazul) {
}

Să vedem un exemplu: clasa umană are o metodă inițiată și o metodă inițială.

clasa HumanBeing {
nume var: șir
init (nume: String) {
self.name = nume
}
comoditate init () {
self.init (nume: „nu este setat”)
// Comunicare init convenție metoda init desemnată
}
}
let humanBeingObj1 = HumanBeing () // apelează la init initia
let humanBeingObj2 = HumanBeing (nume: „abhilash”) // apelează inițiat
Convenience init inițializează metoda init desemnată apelând auto.init.

Inițializator Delegație pentru tipuri de clase

Pentru a simplifica relațiile dintre inițiatorii desemnați și convenienți, Swift aplică următoarele trei reguli pentru apelurile de delegare între inițiatori:

  • Un inițiator desemnat trebuie să apeleze un inițiator desemnat din superclasa sa imediată. Un inițializator desemnat al unei subclase nu poate apela la o inițiativă convențională din superclasa sa. Dacă încercați să faceți acest lucru, veți primi o eroare spunând „eroare: trebuie să apelați la un inițiator desemnat al superclasei”.
  • Un inițiator inițial trebuie să apeleze un alt inițiator din aceeași clasă.
  • Un inițiator inițial trebuie să apeleze la un inițiator desemnat.

Aruncați o privire la următoarea imagine, astfel încât să fie mai clar:

sursa: docuri de mere

Moștenirea inițializatorului automat

Subclasele nu moștenesc inițializatorii de superclase în mod implicit. Cu toate acestea, inițializatorii de superclase sunt moșteniți automat dacă sunt îndeplinite anumite condiții.

Dacă furnizăm valori implicite pentru orice proprietăți noi introduse într-o subclasă, se aplică următoarele două reguli:

  • Regula 1: Dacă subclasa dvs. nu definește nicio inițiator desemnată, moștenește automat toate inițiatorile desemnate de superclasa.
  • Regula 2: Dacă subclasa dvs. furnizează o implementare a tuturor inițiatorilor desemnați ai superclasei - fie prin moștenirea lor conform regulii 1, fie prin furnizarea unei implementări personalizate ca parte a definiției sale, atunci moștenește automat toate inițiatorile de comoditate ale superclasei.

Luați în considerare următorul exemplu și metodele init disponibile pentru a crea un obiect de clasă Man.

clasa HumanBeing {
nume var: șir
init (nume: String) {
self.name = nume
}
comoditate init () {
self.init (nume: „nu este setat”)
// Comoditatea init apelează metoda init desemnată
}
}
let humanBeingObj1 = HumanBeing () // apelează la init initia
let humanBeingObj2 = HumanBeing (nume: „abhilash”) // apeluri
desemnat init
____________________
class Man: HumanBeing {
vârsta var: Int = 0
înlocuire init (nume: String) {
super.init (nume: nume)
}
init (nume: șir, vârstă: Int) {
super.init (nume: nume)
self.name = nume
self.age = varsta
}
}
_______________________
let manObj1 = Man () // apelează comoditatea init a clasei umane
let manObj2 = Man (nume: „Robert”) // apelează overriden init
let manObj3 = Man (nume: „John”, vârsta: 10) // apelează inițiativă personalizată
manObj1.name // imprime „nu este setat”
manObj2.name // tipărește „Robert”
manObj3.name // tipărește „John”

De unde să plec de aici:

Inițializatori în partea rapidă 2: Eșecuri inițializatoare în rapid

Dacă v-a plăcut să citiți această postare și ați găsit-o utilă, vă rugăm să o împărtășiți și să o recomandați pentru ca alții să o poată găsi !!!!

Mulțumiri!!