2016-02-16 14 views
5

Mam kilka klas, które dziedziczą po klasie bazowej. Zwykle z klasami C++ użyłem do przepisania konstruktora na elementach podrzędnych, a następnie wywołania rodzica.Wywołanie konstruktora nadrzędnego podczas inicjowania podklasy w Swift

Czy istnieje sposób w Swift, aby wywołać konstruktora macierzystego, gdy init jest podklasą bez przepisywania go?

internal class A { 
    init(aBool: Bool? = false) { 
     ... 
    } 
} 

class B: A { 
    init(aString: String) { 
     ... 
    } 
} 

Mając te dwie klasy jako przykład, chciałbym init B za pomocą konstruktora:

let obj = A(true) 

Odpowiedz

7

The rules from Apple stwierdzają, że:

[S] ubclasses nie dziedziczą swoje nadklasy inicjatorów domyślnie. Jednak inicjatory nadklasy są automatycznie dziedziczone, jeśli spełnione są określone warunki. W praktyce oznacza to, że nie trzeba pisać nadpisań inicjalizatora w wielu typowych scenariuszach i można dziedziczyć inicjatory superklasy przy minimalnym wysiłku, kiedy tylko jest to bezpieczne.

Zakładając, że podasz wartości domyślnych dla wszystkich nowych właściwości, które wprowadzają w podklasie, dwa następujące zasady:

Zasada 1: Jeśli podklasa nie definiuje każdy wyznaczony przez inicjatorów, automatycznie dziedziczy wszystkie jego nadklasa to inicjatory.

Reguła 2: Jeśli twoja podklasa zapewnia implementację wszystkich swoich inicjalizatorów klasy nadklasy - dziedzicząc je zgodnie z regułą 1 lub wprowadzając niestandardową implementację jako część definicji - to automatycznie dziedziczy wszystkie superlasy ułatwiające inicjalizację.

Te zasady obowiązują nawet wtedy, gdy twoja podklasa zapewnia dodatkowe ułatwienia inicjalizacji.

Co to wszystko znaczy? Jeśli sprawisz, że inicjator podklasy B będzie inicjatorem wygody, wtedy B powinien dziedziczyć wszystkie oznaczone inicjatory A.

class B: A { 
    convenience init(aString: String) { ... } 
} 
2

Jeśli się B „s init, a convenience init nie będzie maskować i oryginalny init będziesz w stanie to zrobić ...

class A { 
    var b: Bool? = nil 
    init(aBool: Bool? = false) { 
     self.b = aBool 
    } 
} 

class B: A { 
    var s: String? = nil 
    convenience init(aString: String) { 
     self.init(aBool: false) 
     self.s = aString 
    } 
} 

let obj1 = A(aBool: true) // obj1 is now an A, obviously. 
let obj2 = B(aBool: true) // obj2 is now a B 

Musisz uważać na domyślne lub inaczej ustawić wszystkie właściwości, chociaż ...

Alternatywnie można override oryginalnego init w B i po prostu zadzwoń super.init.

Powiązane problemy