Swift: как избежать перезаписи этого init() во всех наследуемых классах?

У меня есть этот класс и протокол в рамках:

public protocol P {}

open class C {
    public init(_ p: P.Type) {
        //super.init() etc
    }
}

И в проекте с использованием этого фреймворка:

enum E: P {
    // cases...
}

Меня беспокоит то, что для каждого класса, который наследует C, мне нужно определить один и тот же init() следующим образом:

final class C1: C {
    init() {
        super.init(E.self)
    }
}

final class C2: C {
    init() {
        super.init(E.self)
    }
}

// etc...

Есть ли способ объявить это значение по умолчанию init в моем проекте, например, используя расширение следующим образом:

extension C {
    // Declare the init(E.self) here somehow?
}

Таким образом, я бы просто вызывал C1(), C2() и т. д., не определяя их в подклассе.

Спасибо за вашу помощь.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
48
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете создать протокол, содержащий инициализацию, расширить протокол и предоставить реализацию по умолчанию, а также назначить протокол C.

public protocol P {}

enum E: P {
}

protocol A {
    init(_ p: P.Type)
}

extension A {
    init(_ p: P.Type) {
        // Add a default implementation
        self.init(E.self)
    }
}

class C: A {
    // If you want to override, note you need to add `required`
    required init(_ p: P.Type) {
    }
}

class C1: C {
    // No need to init here
}

Или, если вам не нужен другой протокол, вам понадобится новый класс, который реализует инициализацию и подкласс C, и ваши C1 и C2 наследуют этот новый класс. Это то, что обычно делается, когда люди создают BaseUIViewController и делают свои подклассы UIViewControllers:

public protocol P {}

enum E: P {
}

class C {
    init(_ p: P.Type) {
    }
}

class CBase: C {
    // Override and provide default implementation
    override init(_ p: P.Type) {
        super.init(E.self)
    }
}

class C1: CBase {
    // No need to init here
}

class C2: CBase {
    // No need to init here
}

Объявить удобный инициализатор

extension C
{
    public convenience init()
    {
        self.init(E.self)
    }
}

let c1 = C1()
let c2 = C2()

Или вы можете поместить инициализатор удобства в основное определение C.

Другие вопросы по теме