Can my class override protocol property type in Swift?

5 Solutions Collect From Internet About “Can my class override protocol property type in Swift?”

Requiring AnyObject in the protocol means the children array must be able to accept AnyObject entries. But it sounds like you want Bar‘s children to be only Foo objects.

Instead, you can give the protocol an associated type:

protocol Parent {
    associatedtype Child
    var children: [Child] { get set }
}

class Foo { }

class Bar: Parent {
    var children = [Foo]()
    init() {}
}

If you always want an array of type AnyObject you have to specify it in your class:

class Bar: Parent {
    var children = [AnyObject]()
    init() {}
}

but if you can use a more specific protocol with a typealias you can rewrite you protocol like so:

protocol Parent {
     // in Swift 1 and 2: use `typealias` instead of `associatedtype`
     associatedtype T: AnyObject // this makes sure that all instances in the array are definitely of type `AnyObject` / classes
     var children: [T] { get set }
}

This way your former conformance of your class works but you have to consider that this protocol can only be used as generic constraint and therefore only in functions and generic declarations:

// --- this does work
func someFunc<T: Parent, U: Parent>(p1: T, p2: U) { /* ... */ }

class SomeClass<T: Parent> { /* ... */ }


// --- this doesn't work
let parent: Parent
let array: [Parent]
// here you can only use types which conform to the protocol
// but not the protocol itself as generic arguments
let something = SomeClass<Parent>()

If the protocol declares that there is getter and setter of type [AnyObject] than it means that there have to be such a getter and setter, not subtype of that class.

Your code would be logically wrong – because you would be able to set, for example some [Int] (protocol says it’s possible) to the variable of type [Foo] (class have only this var)

So this is actually the only right way.

protocol Parent {
    var children: [AnyObject] { get set }
}

class Foo {
}

class Bar: Parent { //error happens here
    var children = [AnyObject]()

    init() {}
}

In swift 2.0 typealias might be another option.

No you can’t change the type of a property.

Add this to your bar class:

var childrenObject: Foo {
    get {
        return self.children as! Foo
    }
}

Alternative to the protocol answer that may give you some benefits a protocol doesn’t.

class Parent<T : RawRepresentable> where T.RawValue == Int {
    var value : T

    init(withValue v : T) {
        self.value = v
    }
}

enum testOne : Int {
    case one
    case two
}

enum testTwo : Int {
    case three
    case four
}

class ChildOne : Parent<testOne> {}

class ChildTwo : Parent<testTwo> {}

let c1 = ChildOne(withValue: testOne.one)
print(c1.value)
let c2 = ChildTwo(withValue: testTwo.three)
print(c2.value)

Related: How in Swift specify type constraint to be enum?