0

I have this class and protocol in a framework:

public protocol P {}

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

And in the project using this framework:

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

The thing that bugs me is that for every class that inherits C, I need to define the same init() like this:

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

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

// etc...

Is there a way for me to declare this default init in my project, like using an extension this way:

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

This way, I would simply call C1(), C2() etc without defining it in the subclass.

Thanks for your help.

Rob
  • 4,123
  • 3
  • 33
  • 53

2 Answers2

1

You could create a protocol that contains the init, extend the protocol and provide a default implementation, and assign the protocol to 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
}

Or if you don't want another protocol, you will need a new class that implements the init and subclass C and have your C1 and C2 inherit this new class. Its what is usually done when people create BaseUIViewController and make their UIViewControllers subclasses of this:

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
}
gmogames
  • 2,993
  • 1
  • 28
  • 40
0

Declare a convenience initialiser

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

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

Or you can put the convenience initialiser in the main definition of C.

JeremyP
  • 84,577
  • 15
  • 123
  • 161