如何在 Swift 3 的子类中覆盖 Init()

How to override Init() in the subclass in Swift 3

我在 Swift 还是初学者。我有一个 class NonPlayerCharacter 作为父 class 和一个从它继承的子class Goblin。我在 NonPlayer class 中定义了健康和力量,并且在 Goblin 中定义了武器。然后我声明一个新变量,这样我就可以调用 class Goblin 并更改健康、力量和武器的值,但我看不到括号内的武器(我只看到健康和力量)。我试图创建一个 init 函数,但出现此错误“ Super.init 在从初始化器返回之前未在所有路径上调用”。我在我的代码下面的评论中更清楚地解释了我的问题。

我在操场上有这个 class

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.

所以你有两种方式来处理你的案子:

1 为你的子class创建一个自己的初始化器,调用超级初始化器,然后像这样初始化武器属性

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"
  }
}

然后你就可以像这样创建一个地精了:

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

2 为你的子 class 创建一个方便的初始化器,以便能够决定你是只想调用父 class 的初始化器(设置健康和功率)还是方便的初始化器(设置生命值、力量和武器)像这样:

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"
  }
}

然后你就可以像这样创建一个地精了:

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

或者像这样:

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

进一步阅读here and here

我是这样解决的。它有效,但我不知道使用 'convenience init' 和不使用哪个更好。

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()