Existe-t-il un moyen de créer une classe abstraite dans le langage Swift, ou est-ce une limitation tout comme Objective-C? Je voudrais créer une classe abstraite comparable à ce que Java définit comme une classe abstraite.
141
Existe-t-il un moyen de créer une classe abstraite dans le langage Swift, ou est-ce une limitation tout comme Objective-C? Je voudrais créer une classe abstraite comparable à ce que Java définit comme une classe abstraite.
Réponses:
Il n'y a pas de classes abstraites dans Swift (tout comme Objective-C). Votre meilleur pari sera d'utiliser un protocole , qui est comme une interface Java.
Avec Swift 2.0, vous pouvez ensuite ajouter des implémentations de méthodes et des implémentations de propriétés calculées à l'aide d'extensions de protocole. Vos seules restrictions sont que vous ne pouvez pas fournir de variables ou de constantes membres et qu'il n'y a pas de répartition dynamique .
Un exemple de cette technique serait:
Notez que cela fournit des fonctionnalités comme des "classes abstraites" même pour les structures, mais les classes peuvent également implémenter le même protocole.
Notez également que chaque classe ou structure qui implémente le protocole Employee devra déclarer à nouveau la propriété annualSalary.
Surtout, notez qu'il n'y a pas de répartition dynamique . When
logSalary
est appelé sur l'instance stockée en tant que,SoftwareEngineer
il appelle la version remplacée de la méthode. Lorsqu'ellelogSalary
est appelée sur l'instance après avoir été convertie en anEmployee
, elle appelle l'implémentation d'origine (elle ne distribue pas dynamiquement à la version remplacée même si l'instance est en fait unSoftware Engineer
.Pour plus d'informations, regardez la superbe vidéo WWDC sur cette fonctionnalité: Créer de meilleures applications avec des types de valeur dans Swift
la source
protocol Animal { var property : Int { get set } }
. Vous pouvez égalementfunc logSalary()
à la déclaration de protocole Employee, l'exemple s'imprimeoverridden
pour les deux appels àlogSalary()
. C'est dans Swift 3.1. Ainsi, vous bénéficiez des avantages du polymorphisme. La méthode correcte est appelée dans les deux cas.Notez que cette réponse est destinée à Swift 2.0 et supérieur
Vous pouvez obtenir le même comportement avec les protocoles et les extensions de protocole.
Tout d'abord, vous écrivez un protocole qui agit comme une interface pour toutes les méthodes qui doivent être implémentées dans tous les types qui s'y conforment.
Ensuite, vous pouvez ajouter un comportement par défaut à tous les types qui s'y conforment
Vous pouvez maintenant créer de nouveaux types en implémentant
Drivable
.Donc, fondamentalement, vous obtenez:
Drivable
les implémententspeed
Drivable
(accelerate
)Drivable
est garanti de ne pas être instancié car il ne s'agit que d'un protocoleCe modèle se comporte en fait beaucoup plus comme des traits, ce qui signifie que vous pouvez vous conformer à plusieurs protocoles et prendre des implémentations par défaut de l'un d'entre eux, alors qu'avec une superclasse abstraite, vous êtes limité à une simple hiérarchie de classes.
la source
UICollectionViewDatasource
,. Je voudrais supprimer tout le passe-partout et l'encapsuler dans un protocole / extension séparé, puis le réutiliser par plusieurs classes. En fait, le modèle de modèle serait parfait ici, mais ...Je pense que c'est le plus proche de Java
abstract
ou C #abstract
:Notez que, pour que les
private
modificateurs fonctionnent, vous devez définir cette classe dans un fichier Swift séparé.EDIT: Pourtant, ce code ne permet pas de déclarer une méthode abstraite et donc de forcer son implémentation.
la source
Le moyen le plus simple consiste à utiliser un appel à
fatalError("Not Implemented")
dans la méthode abstraite (non variable) sur l'extension de protocole.la source
(MyConcreteClass() as MyInterface).myMethod()
mais c'est le cas! La clé est d'incluremyMethod
dans la déclaration de protocole; sinon, l'appel se bloque.Après avoir lutté pendant plusieurs semaines, j'ai finalement réalisé comment traduire une classe abstraite Java / PHP en Swift:
Cependant, je pense qu'Apple n'a pas implémenté de classes abstraites car il utilise généralement le modèle de protocole délégué + à la place. Par exemple, le même modèle ci-dessus serait mieux fait comme ceci:
J'avais besoin de ce type de modèle parce que je voulais vulgariser certaines méthodes dans UITableViewController telles que viewWillAppear, etc. Cela vous a-t-il été utile?
la source
Il existe un moyen de simuler des classes abstraites à l'aide de protocoles. Ceci est un exemple:
la source
Une autre façon d'implémenter une classe abstraite consiste à bloquer l'initialiseur. Je l'ai fait de cette façon:
la source
J'essayais de créer une
Weather
classe abstraite, mais utiliser des protocoles n'était pas idéal car je devais écrire les mêmesinit
méthodes encore et encore. Étendre le protocole et écrire uneinit
méthode posait ses problèmes, d'autant plus que j'utilisaisNSObject
conforming toNSCoding
.J'ai donc proposé ceci pour la
NSCoding
conformité:Quant à
init
:la source
Déplacez toutes les références aux propriétés abstraites et aux méthodes de la classe de base vers l'implémentation de l'extension de protocole, où Self contrainte vers la classe de base. Vous aurez accès à toutes les méthodes et propriétés de la classe de base. En outre, le compilateur vérifie l'implémentation des méthodes abstraites et des propriétés dans le protocole pour les classes dérivées
la source
Avec la limitation d'aucune répartition dynamique, vous pouvez faire quelque chose comme ceci:
la source