Рассмотрим следующую иерархию классов в Swift:Наследовать от класса с помощью частного инициализатора?
GMSMarker класс предоставляются библиотекой GoogleMaps. Он имеет два открытых инициализатора (один назначенный, одно удобство).
MapItem, ClusterItem и Cluster являются частью моей модели. Я не хочу разрешать создание объектов MapItem; только ClusterItems и Clusters. Так как Swift не имеет абстрактных классов, для меня будет достаточно частного инициализатора. Однако, учитывая, что MapItem наследует GMSMarker с помощью конструктора удобства, я не могу просто переопределить назначенный инициализатор как закрытый.
Учитывая правила наследования инициализатора в Swift, единственный способ предотвратить создание класса MapItem - это объявить новый закрытый инициализатор с другой подписью, чтобы инициализаторы базового класса не были унаследованы ,
class MapItem : GMSMarker {
private init(dummyParam: Int) {
super.init()
}
}
Пока все хорошо. Теперь, пытаясь создать мой инициализатор для класса ClusterItem, я столкнулся с проблемой.
class ClusterItem : MapItem {
weak var post: Post?
init(post: Post) {
self.post = post
super.init(dummyParam: 0)
}
}
Я получаю следующее сообщение об ошибке компилятора на линии, которая вызывает super.init(): 'MapItem' does not have a member named 'init'
.
Если я опускаю вызов super.init, я получаю следующую ошибку: Super.init isn't called before returning from initializer
.
Есть ли способ выполнить то, что я хочу в быстром. Я хотел бы сохранить иерархию наследования, если это возможно, потому что MapItem содержит некоторый общий код реализации для ClusterItem и Cluster. Кроме того, я хотел бы иметь возможность ссылаться на ClusterItems и Clusters, используя коллекцию MapItems.
Сделать его «внутренним», а не «частным». Или объявите классы в одном файле, тогда 'private' не будет проблемой. – Sulthan
Спасибо @Sulthan, объявив классы в том же файле. Исходя из мира C++/C#, управление доступом Swift занимает некоторое время, чтобы привыкнуть. – Dragonspell