Search code examples
swiftprotocols

Different Protocol with similar property name


I have a class bird which confirms two protocols swim and fly. Both the protocol have similar property called Speed. As Bird can fly with some speed also birds can swim with some speed. I am confirming both the protocol in one class bird.

My question is

a) How can I distinguish between both the speed (If I want to keep similar names of properties) ?

b)In the current code snippet under class bird there is a property speed, to which protocol this property is referring to (Fly or Swim)?

c) How can I know flying speed and swimming speed in this scenario?

protocol Fly {
    var speed: Int { get set }
}


protocol Swim {
    var speed: Int { get set }
}


class Bird: Fly, Swim
{
    var speed: Int = 0 <-------- Is this from protocol swim or from Fly 
     
}

Solution

  • I feel like you've misinterpreted the concept of protocol. Very straightfowardly, a protocol states what properties (speed in your example) and methods something (the Bird class, in your example) must have in order to conform to it. Any type that satisfies the requirements of a protocol is said to conform to that protocol. Protocols are an important concept in the delegate pattern.

    So, I'll answer to your b) question first: since your Bird class have a speed property, it conforms to both protocols. That's because your protocols have different names but define the same blueprint of properties that the class must have. That would not be true in the following case:

    protocol Fly {
        var speed: Int { get set }
    }
    
    protocol Swim {
        var speed: Int { get set }
        func startSwimming() 
    }
    
    // you'll get a compiler error here
    class Bird: Fly, Swim 
    {
        var speed: Int = 0    
    //    uncommenting these lines will solve the compiler error
    //    func startSwimming() 
    //    {
    //         print("started to swim")
    //    }
    }
    

    The class then conforms to the Fly protocol, but not to the Swim protocol. You need to add the startSwimming() method, in my example, or you'll get an error from the compiler here. It would be the same if instead of a method the Swim protocol included another property.

    a) question: you can't, in your example. One solution would be to split speed into two different properties, like this:

    protocol Fly {
        var flyingSpeed: Int { get set }
    }
    
    protocol Swim {
        var swimmingSpeed: Int { get set }
    }
     
    class Bird: Fly, Swim
    {
        var flyingSpeed: Int = 0
        var swimmingSpeed: Int = 0
    }
    

    Or, just to show you a convention to write code - note that it's the same of the above code:

    class Bird
    { 
        // ...
    }
    
    extension Bird: Fly 
    {
        var flyingSpeed: Int = 0
    }
    
    extension Bird: Swim 
    {
        var swimmingSpeed: Int = 0
    }
    

    Not sure about what you meant with your c) question. If I understood it correctly, of course you can't create an instance of a protocol, something like let swim = Swim() makes no sense. You can however create a bird object and access both properties from it.

    let bird = Bird()
    print(bird.flyingSpeed) // this will print 0 in the console
    print(bird.swimmingSpeed) // this will print 0 in the console
    bird.flyingSpeed = 4 
    bird.swimmingSpeed = 3
    print(bird.flyingSpeed) // this will print 4 in the console
    print(bird.swimmingSpeed) // this will print 3 in the console
    

    If however you were asking about the delegate pattern, shortly, it is used to "communicate" between classes. You can find lot of clear explanations about it just by searching on Google. Just a few suggestions:

    1. StackOverflow related question and answers.

    2. YouTube tutorial by iOS Academy about delegate pattern.