Как сделать множественное наследование swift

Обновлено: 03.07.2024

Я просто не знаю, как его инициализировать с моего основного ViewController. Когда я пытаюсь сделать следующее, он жалуется, что ViewController не соответствует CBCentralManagerDelegate:

Это потому, что вы не можете иметь множественное наследование в Swift. Вы можете иметь столько протоколов, сколько хотите, но только один суперкласс.

Когда вы пишете vaBean(delegate: self, queue: nil) , self ссылается на ViewController, который не может служить делегатом, поскольку он не соответствует протоколу делегата. Я думаю, что вам лучше всего изменить свой собственный инициализатор так, чтобы он принимал только параметр queue , и установить для него значение self.delegate = self - в контексте инициализатора self будет ссылаться на ваш экземпляр vaBean, что вам и нужно.

4 ответа

Swift и Objective-C являются единственным наследованием, у вас не может быть более одного суперкласса для класса.

Когда вы видите код Swift с тем, что выглядит как несколько суперклассов в объявлении, вы увидите, что самое большее одно из имен в объявлении является суперклассом, другие - именами протоколов.

В Objective-C они были бы написаны с помощью , но это не относится к Swift.

Swift не поддерживает множественное наследование. Но ваш ViewController не нуждается в наследовании от vaBeanDelegate, если вы просто хотите получить к нему доступ, как предполагает ваш вопрос.

Вам нужно будет показать больше кода (особенно подпись инициализатора для vaBean который вы вызываете). Что требуется от vaBean delegate ?

Я пытаюсь сделать что-то очень простое, но изо всех сил. Я хочу отдельный файл (класс), который является просто наследованием CBCentralManager - так что он может обрабатывать Bluetooth. У меня был код, работающий в основном ViewController, но я хотел переместить его, чтобы я мог следовать этике MVC.

Ваш ViewController не соответствует протоколу CBCentralManagerDelegate

Первый аргумент конструктора init нуждается в объекте, который соответствует протоколу CBCentralManagerDelegate. Вы передаете туда self, который является вашим контроллером представления, который не реализует этот делегат (даже если он еще не определяет никаких функций.

У вас есть 2 варианта: 1) Реализуйте CBCentralManagerDelegate непосредственно в вашем контроллере представления, объявив его следующим образом:

2) Добавьте расширение к классу в конце вашего файла, которое добавляет соответствие для протокола

Если параметры типа SomeSubClass и SomeOtherSubClass наследуются от общего базового класса SomeBaseClass .

Теперь я хочу определить переменную для хранения экземпляров как SubClassOne и SubClassTwo . Я пробовал много возможностей:

Но первая попытка приводит к ошибке Reference to generic type 'BaseClass' requires arguments in , а два других результата приводят к ошибке. Cannot assign value of type 'SubClassOne' to type. при попытке назначить стоимость. Я даже пытался обмануть компилятор Swift, чтобы вывести этот тип для меня, инициализируя массив:

Но даже это не удалось, что привело к ошибке. Heterogeneous collection literal could only be inferred to [Any]; add explicit type annotation if this is intentional Heterogeneous collection literal could only be inferred to [Any]; add explicit type annotation if this is intentional . В самом деле, единственным типом аннотации, который успешно позволяет AnyObject оба подкласса, является Any или AnyObject . Можно ли хранить эти экземпляры с более конкретным типом? Если нет, то почему?

Причина, по которой это важно, заключается в том, что я в конечном итоге хочу получить свойство prop из хранимой переменной obj . Я не могу это сделать, если obj хранится как Any . Я также не могу просто передать его SubClassOne или SubClassTwo потому что сам метод, в котором я пытаюсь получить доступ к свойствам, является универсальным методом, а метод SubClassOne или SubClassTwo для SubClassTwo зависит от параметра типового типа метода:

Который castObj(asType: SubClassOne.self) как: castObj(asType: SubClassOne.self) или castObj(asType: SubClassTwo.self) . Тем не менее, мы сталкиваемся с одной и той же проблемой: единственное ограничение типа типа, которое я могу определить, которое принимает как SubClassOne и SubClassTwo – это Any , а затем компилятор Swift жалуется: Value of type 'T' has no member 'prop' .

В качестве обходного пути я попытался определить протокол, который инкапсулирует требуемое свойство:

Затем я добавил это к объявлению SubClassOne и SubClassTwo . Однако это привело к еще одной ошибке: Type 'SubClassOne' does not conform to protocol 'HasProp' . Это меня тоже смущает, поскольку SubClassOne и SubClassTwo оба наследуют prop из BaseClass и поэтому фактически соответствуют протоколу.

  1. Возможно ли хранить экземпляры SubClassOne и SubClassTwo с более конкретным типом, который дает доступ к свойствам BaseClass ? Если нет, то почему?
  2. Почему субклассы не соответствуют протоколу, как ожидалось?
  3. Как я могу изменить дизайн, чтобы достичь желаемого поведения?

Проблема в том, что на данный момент функция castObj не имеет ограничений типа для своего общего параметра T Предоставляя ограничение типа BaseClass вы должны быть в порядке, поскольку у BaseClass есть оба свойства.

В вашем примере тип propTwo был общим для обоих подклассов, и тип propOne был специализированным. Сделайте свой дизайн таким.

Дело в том, чтобы держать общие вещи в базовом классе и составлять ваши специализации.

Существует фундаментальное заблуждение, что SubclassOne и SubclassTwo находятся в одной иерархии наследования. Из-за типичного типа они наследуются от разных базовых классов. Вы не можете смешивать и сопоставлять их.

Думаю об этом. С наследованием вы должны иметь возможность использовать любой подкласс везде, где у вас есть базовый класс, поэтому в вашем тестовом примере:

Какой тип должен иметь правая часть следующих выражений?

testArray [0].prop = что-то

testArray [1].prop = что-то;

В SubClassOne , тип prop является SomeSubClass и SubClassTwo тип prop должны быть SomeOtherSubClass .

Единственный способ заставить вас работать, так как prop должен быть объявлен как SomeBaseClass и устраняет необходимость использования BaseClass .

редактировать

Почему протокол не работает?

Проблема с протоколом заключается в том, что вы определяете свойство как имеющее тип базового класса, но оно читается/записывается. Свойство в реализации протокола не может выполнить контракт со свойством, которое специализировано для одного из подклассов, потому что другие биты кода должны иметь возможность назначить любой экземпляр базового класса для свойства.

В продолжении обучения переходим на новый уровень —
объектно — ориентированное программирование.

Формат обучения: онлайн + домашние задания

Курс подойдет студентам

Преподаватель и куратор курса:

Объектно - ориентированное программирование в Swift

💻 78 видео уроков

Вы их изучаете в удобном для себя темпе.

📄 Домашние задания

После прохождения каждой темы выполняйте домашние задания.

⚡ Базовые знания

После успешного прохождения этого курса вы получаете базовые знания в Swift

Чему вы научитесь на курсе?

Использовать основные принципы разработки в Swift

Вы будете готовы приступить к изучению разработке приложений

Продолжение курса Swift с нуля.

Большинство инфраструктур Apple имеют объектно-ориентированную архитектуру. Прежде чем приступить к разработке iOS / MacOS, вы должны сначала понять объектно-ориентированное программирование и шаблоны проектирования. В этом курсе мы рассмотрим основные понятия и шаблоны проектирования, чтобы вы начали разработку приложений.

Объектно-ориентированное программирование — это фундаментальная парадигма программирования, которую вы должны освоить, если серьезно относитесь к изучению Swft. Объектно-ориентированное программирование лежит в основе большинства фреймворков, с которыми вы будете работать.

Объекты могут использоваться для моделирования почти чего угодно — координат на карте, касания экрана, даже колебания процентных ставок на банковском счете и тд.

На замену Objective-C пришел Swift в приложениях для iOS устройств и Mac OS X. На него оказали влияние такие языки как Python, Ruby, Haskel и конечно же Objective-C.Apple описала язык Swift как “Objective-C без С”. Язык действительно получился удобным, мощным и продуманным.

Вам ответят команда поддержки Хекслета или другие студенты.

Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?
  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

Читайте также: