Jeśli oświadczamSwift: "failable inicjator 'init()' nie może przesłonić non-failable inicjator" vs. domyślnymi parametrami
public class A: NSObject {
public class X { }
public init?(x: X? = nil) { }
}
wszystko jest w porządku. Gdy używa się go jak let a = A()
, inicjator jest wywoływany zgodnie z oczekiwaniami.
Teraz chciałbym mieć klasę zagnieżdżoną X
prywatną, a także sparametryzować init
(oczywiście musi to być). Ale prosty init?()
powinien pozostać publicznie dostępny, tak jak był wcześniej. Więc piszę
public class B: NSObject {
private class X { }
private init?(x: X?) { }
public convenience override init?() { self.init(x: nil) }
}
Ale to daje błąd z init?()
inicjatora: failable inicjująca 'init()' nie może przesłonić non-failable inicjator z przesłonięte initializer będąc public init()
w NSObject
.
W jaki sposób mogę skutecznie zadeklarować inicjator A.init?()
bez konfliktu, ale nie pod numerem B.init?()
?
Pytanie dodatkowe: Dlaczego nie można zastąpić inicjalizatora, który nie może ulec awarii, błędnym? Odwrotna sytuacja jest prawidłowa: mogę unieważnić inicjator failable, który nie jest uszkodzony, co wymaga użycia wymuszonego super.init()!
i tym samym wprowadza ryzyko błędu runtime. Dla mnie, pozwolenie, aby podklasa miała wadliwy inicjator, wydaje się rozsądniejsze, ponieważ rozszerzenie funkcjonalności wprowadza większe ryzyko niepowodzenia. Ale może czegoś tu brakuje - wyjaśnienie bardzo doceniane.
'override' oznacza metodę z tą samą sygnaturą w superklasie. Jednak w 'NSObject' nie ma' init? ' – vadian
@vadian: Tak, ale pomijanie' override' powoduje wyświetlenie komunikatu o błędzie 'nadpisująca deklaracja wymaga" override "słowa kluczowego', więc i tak liczy się jako nadpisująca. Napraw - wstawia 'override', dając inny błąd. Co więcej, jestem upoważniony do przesłonięcia niezawartego init z nie-failable, ale nie na odwrót. – Stefan