33 votes

Protocoles de classe uniquement dans Swift

Je veux que certaines de mes classes (pas toutes) soient conformes en utilisant des «protocoles de classe uniquement» de la documentation. Ce que je fais c'est

 protocol RefreshData: class, ClassA, ClassB
{
    func updateController()
}
 

et je reçois les erreurs

 non class type 'RefreshData cannot inherit from classA
non class type 'RefreshData cannot inherit from classB
 

Je ne suis pas sûr de suivre exactement comme dans les documents. Quelqu'un a-t-il des idées à ce sujet?

41voto

Wain Points 65967

Swift 4 vous permet de combiner des types, de sorte que vous pouvez avoir votre protocole, puis de créer, par exemple, un alias de type à l'associer à une classe spécifique de l'exigence.

Pour (artificiel) exemple:

typealias PresentableVC = UIViewController & Presentable

Pour le code:

Le problème, c'est que vous essayez de vous limiter à des classes spécifiques et Swift ne peut pas le faire (pour le moment en tout cas). Vous ne pouvez limiter aux classes et hériter d'autres protocoles. Votre syntaxe est le protocole de l'héritage, mais vous essayez de l'utiliser comme une classe de limitation.

Notez que le but de la classe de protocoles est:

Utiliser une classe-protocole uniquement lorsque le comportement défini par que les exigences du protocole suppose ou implique qu'une conformation de type a référence sémantique plutôt que de valeur sémantique.

28voto

appzYourLife Points 10219

Les réponses fournies par Chris et Wain sont corrects. Je suis simplement en ajoutant un peu plus de détails ici.

Définition d'un protocole

Il faut distinguer la notion de déclarer un protocol (disponible pour les classes)

protocol RefreshData: class {
    func updateController()
}

La définition d'une classe

...de la notion de conformité de votre classe à un protocole

class ClassA: RefreshData {
    func updateController() {

    }
}

Conforme à une classe qui ne vous appartient pas

Parfois, vous souhaitez de se conformer d'une classe à un protocole, mais vous n'avez pas le code source de cette classe. Dans ce cas, vous pouvez utiliser un extension

extension ClassB: RefreshData {
    func updateController() {

    }
}

10voto

La dernière version de Swift peut le faire! Je ferais un protocole et des extensions de protocoles qui ciblent les classes que vous voulez! (contraindre l'extension à une classe spécifique)

     protocol Movable {
        func moveForward()
        func moveBackward()
    }

    extension Movable where Self: Car {
        func moveForward() {
            self.location.x += 10;
        }

        func moveBackward() {
            self.location.x -= 10;
        }
    }
    extension Movable where Self: Bike {
        func moveForward() {
            self.x += 1;
        }

        func moveBackward() {
            self.x -= 1;
        }
    }

    class Car: Movable {
        var location: CGPoint

        init(atLocation location: CGPoint) {
            self.location = location
        }
    }

    class Bike: Movable {
        var x: Int

        init(atX x: Int) {
            self.x = x
        }
}
 

3voto

Chris Points 1342
protocol RefreshData : class
{
    func updateController()
}

class ClassA : RefreshData
{
    func updateController() {}
}

class ClassB : RefreshData
{
    func updateController() {}
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X