0
votes

I am still a beginner at Swift. I have a class NonPlayerCharacter as a parent class and a subclass Goblin that inherits from it. I defined health and power inside the NonPlayer class, and I defined weapon inside the Goblin. Then I declare a new variable so I can call class Goblin and change the values of health, power, and weapon but I can't see weapon inside the bracket (I only see health and power). I tried to make an init function, but I got this error " Super.init isn't called on all paths before returning from initializer ". I explained my problem more clearly in the comments below inside my code.

I have this class on the Playground

class NonPlayerCharacter 
{

  var health: Int
  var power: Int

init() {

    health = 0
    power = 0

}
 init(health: Int , power : Int) {
    self.health = health
    self.power = power

}

func attack () -> String
{
    return "attack from NonPlayer Character"

}    }

var NonPlayerMethod = NonPlayerCharacter(health: 100, power: 90)

 //and this is the SubClass: 

  class Goblin: NonPlayerCharacter
   {
  var weapon : Int = 0

  override func attack() -> String {
    return "attack from Goblin"
 }
 }



 var GoblinMethod = Goblin(health: 40, power: 12)
 GoblinMethod.weapon = 10
 GoblinMethod.attack()

  //I tried to make initialization like this in the SubClass** 


   class Goblin: NonPlayerCharacter
  {
   var weapon : Int = 0

   Init ( weapon: Int )
   {
   self.weapon = weapon 
   }
   }

   // so I can change the values like this :

   var GoblinMethod = Goblin( weapon: 30 , health: 20, power: 50) 

  // I got this error ( Super.init isn't called on all paths before returning from initializer )
 //I don't think I need to override Init as the weapon only in the SubClass.
2
What does it didn't work mean? - Alexander
When I tried to do it like this, health and power weren't recognized and the value of weapon didn't change and I got an error @Alexander - D.Moses
Am I supposed to be able to guess what the error is? - Alexander
No of course not. I am sorry here is the error. Super.init isn't called on all paths before returning from initializer @Alexander I will edit my question now. - D.Moses
Initializing a Goblin requires the initialization of a NonPlayerCharacter, so you'll need to call super.init(...) at some point in your initializer - Alexander

2 Answers

3
votes

So you have two ways to handle your case:

1 Create an own initializer for your subclass, call the super initializer and after that initialize the weapon property like this

class Goblin: NonPlayerCharacter {
  var weapon : Int = 0

  init(health: Int, power: Int, weapon: Int) {
    super.init(health: health, power: power)
    self.weapon = weapon
  }

  override func attack() -> String {
    return "attack from Goblin"
  }
}

Then you are able to create a Goblin like this:

var goblin1 = Goblin(health: 30, power: 20, weapon: 50)

2 Create a convenience initializer for your subclass to be able to decide if you want to call only the initializer from the parent class (with setting health and power) or the convenience one (with setting health, power and weapon) like this:

class Goblin: NonPlayerCharacter {
  var weapon : Int = 0

  convenience init(health: Int, power: Int, weapon: Int) {
    self.init(health: health, power: power)
    self.weapon = weapon
  }

  override func attack() -> String {
    return "attack from Goblin"
  }
}

Then you are able to create a Goblin like this:

var goblin2 = Goblin(health: 30, power: 20, weapon: 50)

or like this:

var goblin3 = Goblin(health: 30, power: 20)

Further readings here and here

0
votes

I solved it this way. It works but I don't know which one is better between using 'convenience init' and not using.

class NonPlayer {
   private var health: Int
   private var power: Int
   init(health: Int, power: Int) {
    self.health = health
    self.power = power
   }

   func attack() {
    print ("비유저에게 공격당했습니다.")
   }
}

class Goblin: NonPlayer {
    private var weaponDamage: Int
    init(health: Int, power: Int, weaponDamage: Int) {
      self.weaponDamage = weaponDamage
      super.init(health: health, power: power)
    }
    override func attack() {
     print("고블린에게 공격당했습니다.")
    }
}

let goblin = Goblin(health: 200, power: 15, weaponDamage: 20)
goblin.attack()