0

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 
     
}
Kanishka
  • 67
  • 3
  • As long as there is no protocol extension which uses `speed` it’s irrelevant where `speed` belongs to. And even with a protocol extension the compiler should be smart enough to distinguish the type. – vadian Jul 11 '23 at 11:56
  • What, exactly, are you trying to accomplish? – Ron Jul 11 '23 at 12:08
  • If you want to have both air speed and water speed for an animal which adopts both protocols then you need to use different property names. Currently there is only one `speed`, which is shared by both protocols in an animal which adopts both protocols. – Geoff Hackworth Jul 11 '23 at 12:46

2 Answers2

4

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.

oneshot
  • 591
  • 1
  • 5
  • 27
  • 1
    "Any type that satisfies the requirements of a protocol is said to conform to that protocol" That is possibly misleading. The type must _formally adopt_ the protocol in order to conform to it. Merely having a `speed` property does not give a type any relationship at all to Swim or Fly. – matt Jul 11 '23 at 14:37
1

Is this from protocol Swim or from Fly

Neither. It's a property on Bird which satisfies both Swim or Fly. Protocol conformance is different from class inheritance. I clarify this a bit in this other answer: https://stackoverflow.com/a/76632019/3141234

Alexander
  • 59,041
  • 12
  • 98
  • 151
  • You're right, OP intended protocol conformance as the same of class inheritance, that's the reason of his ambiguous questions. I guess once OP understand this all his questions are cleared, I wrote a bunch of lines in my answer but this should actually be the accepted one lol. – oneshot Jul 11 '23 at 14:52
  • @oneshot Yeah, it's a common misunderstanding that I've seen before. Your answer it good, I upvoted it :) – Alexander Jul 11 '23 at 14:58