0

I have a protocol like this:

protocol Robot {
  func beep()
  func boop()
  func explode()
}

And a struct like this:

struct Factory {
  let robot: Robot
  func testRobot() {
    robot.beep()
    robot.boop()
  }
  func killRobot() {
    robot.explode()
  }
}

They both work fine (at least theoretically), and should work for anything with the protocol of Robot.

However, if I have a struct like this:

struct UselessRobot: Robot {
  init() {
    explode()
  }
  func explode() {
    print("BANG")
  }
}

Then XCode won't compile it, since I didn't define beep or boop. But, the functions would be empty if I defined them anyway:

extension Robot {
  func beep() {}
  func boop() {}
  func explode() {}
}

Is there a way to get around this? It seems really weird to be writing lines of code that do nothing.

The Factory accepts any Robot, so it's easier to call beep and boop without worrying about if they work or not, so I'd rather avoid doing some complicated check if possible.

Thanks for any help!

EDIT: This question is the same as this one here, sorry everyone

Community
  • 1
  • 1
MysteryPancake
  • 1,365
  • 1
  • 18
  • 47
  • 2
    Short answer: no. Longer answer: protocols are intended to be light-weight and contain no implementation. This way you can be sure that all the implementation for UselessRobot is actually part of the struct and do not have to search for the protocol Robot that might contain additional implementations. And the line `func beep() {}` contains information - it tells you that for UselessRobot beep will do nothing. – Gerriet May 09 '17 at 10:34
  • Protocols are just definition for functions. not implementations. We have to implement them in class/struct only and write our own logic . – Balaji Galave May 09 '17 at 10:41

2 Answers2

0

As Gerriet said, the short answer is no.

If you define the Robot protocol but some or most robots won't implement beep or boop then your protocol is not really that useful.

You could be more specific though...

protocol Robot {
   func explode() 
}

protocol NoisyRobot: Robot {
   func beep()
   func boop()
}

struct QuietRobot: Robot {
   func explode() {
       print("bang")
   }
}

struct LoudRobot: NoisyRobot {
   func explode() {
       print("bang")
   }

   func beep() {
      print("beep")
   }

   func boop() {
      print("boop")
   }
}
Scriptable
  • 19,402
  • 5
  • 56
  • 72
  • Your `LoudRobot` will need to implement `explode` as well, since structs do not support inheritance – Paulw11 May 09 '17 at 10:43
  • Okay, thanks @Scriptable! But, what would you recommend I do about the Factory? The protocol is helpful for that since it makes it easy to call the functions for whichever Robot happens to be the main one. Is there a better way to do that? – MysteryPancake May 09 '17 at 11:10
  • It depends on how you intend to use it to be honest. will all robots beep and boop? if not do you need those as required functions in the protocol interface? the factory currently only creates a test robot and calls functions on it, what do you need a factory for? are you planning on having lots of robots configured differently? I havent had to use a factory in swift yet to be honest – Scriptable May 09 '17 at 11:13
  • @Scriptable The real 'factory' that I'm using is a GameScene, and the real 'robot' is a base for the levels I'm making in the game. None of the levels override all the available functions, but all functions are in use by some level at some point. It's a tricky situation. I can't find any examples that do this sort of thing, so I'm a bit lost. – MysteryPancake May 09 '17 at 11:47
  • Without knowing alot more about exactly how your going to use this, it's difficult to give an accurate answer. I would recommend watching this from WWDC https://developer.apple.com/videos/play/wwdc2015/408/ it gives a good idea of how to get the benefits of protocols and structure your application properly. You could always use the more specific protocols like i have above. then you can still have an array of objects that conform to the base Robot protocol, and then when you need to be more specific use conditional casting to see which more specific type of robot you have currently – Scriptable May 09 '17 at 11:58
0

How about that:

   protocol Robot {
        //func beep()
        //func boop()
        //func explode()
   }

   extension Robot {
    func beep() {}
    func boop() {}
    func explode() {}
   }

   struct UselessRobot: Robot {
    init() {
        explode()
    }
    func explode() {
        print("BANG")
    }
   }
Mehul Parmar
  • 3,599
  • 3
  • 26
  • 42