2017-02-22 1 views
2

J'essaie de comprendre pourquoi Swift applique une classe conforme à un protocole avec un initialiseur à marquer comme requis. Cela impose essentiellement toutes les sous-classes pour implémenter également cet initialiseur. Sûrement l'initialiseur de superclasse désigné serait hérité?Swift: Initialisation du protocole d'implémentation dans une classe

Les citations ci-dessous sont extraites du Guide Langue: Swift https://developer.apple.com/library/prerelease/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-ID272

Vous pouvez mettre en œuvre une exigence d'initialisation de protocole sur une classe conforme soit comme un initialiseur désigné ou un initialiseur de commodité. Dans les deux cas, vous devez marquer la mise en œuvre de initialiseur avec le modificateur requis:

class SomeClass: SomeProtocol { 
    required init(someParameter: Int) { 
     // initializer implementation goes here 
    } 
} 

class SomeSubclass: SomeClass { 
    required init(someParameter: Int) { // enforced to implement init again 
     // initializer implementation goes here 
    } 
} 

L'utilisation du modificateur requis assure que vous fournir une implémentation explicite ou héritée de l'exigence de initialiseur sur tous les sous-classes de la classe conforme, de sorte qu'elles soient également conformes au protocole .

EDIT: Je ne l'avais pas d'abord mentionné que je suis actuellement limité à Swift 2.1. Il semble être un problème de compilateur dans cette version et ne se produit pas dans les versions ultérieures.

Répondre

3

sûrement serait hérité de la superclasse initialiseur désigné?

Non, pas toujours. Si la sous-classe définit ses propres initialiseurs, elle n'hérite pas automatiquement des initialiseurs désignés par la superclasse. Prenons l'exemple suivant:

class Foo { 
    init() {} 
} 

class Bar : Foo { 

    var str: String 

    init(str: String) { 
     self.str = str 
    } 
} 

let b = Bar() // illegal – what value would the 'str' property have? 

Comme Bar définit son propre init(str:) désigné initialiseur, il ne héritera automatiquement de « s désignés Fooinit() initialiseur. Cela empêche une initialisation dangereuse dans les cas où la sous-classe déclare ses propres propriétés stockées.

Marquage init() comme requiredBar a fait respecter un init(), que ce soit en fournissant sa propre implémentation:

class Foo { 
    required init() {} 
} 

class Bar : Foo { 

    var str: String 

    init(str: String) { 
     self.str = str 
    } 

    // implement required init(), as Bar defines its own designated initialiser. 
    required init() { 
     self.str = "foo" // now str is correctly initialised when calling init() 
    } 
} 

let b = Bar() // now legal 

ou en héritant la mise en œuvre de Foo (lorsque Bar ne définit pas ses propres initialiseurs désignés) :

class Foo { 
    required init() {} 
} 

class Bar : Foo { 
    // inherits init() from Foo, as Bar doesn't define its own designed initialisers. 
} 

let b = Bar() // legal 
+0

Cela a beaucoup de sens pour le raisonnement de le marquer comme requis. Je suppose que ce qui m'a découragé était le fait que dans Swift 2.1, le compilateur vous oblige à implémenter l'initialiseur de superclasses même si la sous-classe n'a pas d'initialiseurs désignés. –

+0

Marquer cela comme accepté car il explique ma question "Sûrement l'initiateur désigné de superclasse serait héritée?" Le problème original que j'avais était dû à une limitation de Swift 2.1. –

2

Vous n'êtes pas obligé d'implémenter l'initialiseur dans la sous-classe. Considérons cet exemple, qui compile très bien:

protocol SomeProtocol { 
    init(someParameter: Int) 
} 


class SomeClass: SomeProtocol { 
    required init(someParameter: Int) { 
     // initializer implementation goes here 
     print(someParameter) 
    } 
} 


class SomeSubclass: SomeClass { 
    // Notice that no inits are implemented here 
} 

_ = SomeClass(someParameter: 123) 
_ = SomeSubclass(someParameter: 456) 
+0

J'aurais dû mentionner que je suis actuellement limité à Swift 2.1 donc cou ld serait un bug dans cette version. Avec quelle version avez-vous compilé? –

+0

Swift 3. Swift 2 est obsolète. – Alexander

+0

Merci d'avoir vérifié la version.Je comprends qu'il est obsolète mais je suis actuellement limité à son utilisation en raison de circonstances hors de mon contrôle. Bon à savoir son été adressé dans les versions ultérieures. –