Search code examples
swiftclassvariablesprotocols

Swift - variable with type equal to protocol


If I: 1. Create a protocol. 2. Create a class which conforms to said protocol. 3. Instantiate said class. 4. Create a new variable = to said instance, making this variable's type = to the protocol.

Why is said new variable only able to perform the protocol function and not any other functions belonging to the class?


Solution

  • Consider the following:

    protocol SomeProtocol {
        func doSomething()
    }
    
    class ClassOne: SomeProtocol {
        func doSomething(){
            print("did something!")   
        }
        func myStuff(){
            print("I'm not a part of the protocol")
        }
    }
    class ClassTwo: SomeProtocol {
        func doSomething(){
            print("did something too!")
        }
        func otherStuff(){
            print("I do other stuff that's not part of the protocol")
        }
    }
    
    var a: SomeProtocol = ClassOne()
    a.doSomething()
    
    //a.myStuff() //this will not compile
    (a as? ClassOne)?.myStuff() //this compiles and will execute
    
    a = ClassTwo()
    
    a.doSomething() //this works too
    (a as? ClassOne)?.myStuff() //compiles but cast will fail at runtime, so func doesn't execute
    (a as? ClassTwo)?.otherStuff() //executes
    

    When executed, this will output:

    did something!

    I'm not a part of the protocol

    did something too!

    I do other stuff that's not part of the protocol

    Basically, if you declare that the variable only has to conform to the protocol, there's nothing to stop you from assigning an instance of a different class, as long as it conforms to the protocol. As you can see above, you can cast it to the appropriate class whenever you need to and, provided it's an instance of that class, you will be able to access its properties and methods.