在Swift类中重写的可选函数?

时间:2017-04-22 05:52:35

标签: ios swift class override optional

我试图用Swift做一个简单的游戏。游戏有不同的级别,每个级别都要求游戏的行为方式略有不同。我决定为每个级别使用不同的类,所有类都继承自基类级别。

这是基础:

import SpriteKit

class LevelBase {

  var scene: GameScene! // Seems very dodgy
  var blocks = [SKSpriteNode]()

  init(scene: GameScene) { // Should this be required init?
    self.scene = scene
  }

  func filterBlock(_ block: SKSpriteNode) {
    blocks = blocks.filter() { $0 !== block } // Looks really dodgy to me
  }

  func update(time: TimeInterval) {
    // For override
  }

  func levelUp() {
    // For override
  }

  func postGenerate() {
    // For override
  }
}

然而,对我来说,这堂课似乎写得非常糟糕。我无法找到任何在类中创建的函数的例子,只是为了被覆盖,这让我觉得我做错了。我应该为这样的可选功能使用扩展或协议吗?我不太明白它们是如何工作的,所以到目前为止我还没有使用它。

第二个问题是这个类需要用游戏场景变量初始化,因为某些级别需要它来添加或删除精灵。考虑到这个类是在游戏场景的文件中创建的,这看起来特别狡猾。

肯定有更好的方法吗?

1 个答案:

答案 0 :(得分:3)

我没有SpriteKit的经验,但从一般的角度来看,你应该考虑"Favour composition over Inheritance"

您将拥有一个不用于子类化的Level类,但可以使用具有不同实现的对象或值进行实例化。

此外,您应该使用协议来定义这些协议,并且可以将默认实现添加为协议扩展。

final class Level {
    init(levelImplementation: LevelImplementationType) {
        self.levelImplementation = levelImplementation
    }

    let levelImplementation: LevelImplementationType

    func navigate()  {
        levelImplementation.navigate()
    }

    func update(timeInterval: TimeInterval) {
        levelImplementation.update(timeInterval: timeInterval)
    }

}

Level将使用符合LevelImplementationType

的对象或结构进行实例化
protocol LevelImplementationType {
    func navigate()
    func update(timeInterval: TimeInterval)
}

默认实施可以通过扩展来完成。

extension LevelImplementationType {
    func navigate() {

    }
    func update(timeInterval: TimeInterval) {

    }
}

LevelImpelmenation需要符合LevelImplementationType,但不会有任何进一步的限制。即他们可以有非常不同的初始化者。

struct LevelImplementation1: LevelImplementationType {
    // useses default implementation of `navigate` and `update` from extension
}

struct LevelImplementation2: LevelImplementationType {
    // useses default implementation of `update` from extension

    func navigate() {
    }
}

struct LevelFileImplementation: LevelImplementationType {
    init(with path: String) {
        // read variables from file at path
    }

    func navigate() {
        // navigate as given in file
    }

}

级别实例可以像

一样创建
let level1 = Level(levelImplementation: LevelImplementation1())
let level2 = Level(levelImplementation: LevelImplementation2())
let level3 = Level(levelImplementation: LevelFileImplementation(with: "path/to/file"))