Понимание того, как превратить классы в протоколы в Swift - PullRequest
1 голос
/ 25 марта 2020

Мой код работает отлично! Но чем больше я изучаю абстрактные классы и протоколы, тем больше начинаю думать, что «logi c», стоящий за моим кодом, совершенно неверен. Позвольте мне объяснить вам более подробно:

У меня есть class с именем SpaceObject, который является своего рода абстракцией для унаследованных классов. Он в основном содержит некоторые свойства и физику. Этот класс не должен быть инициализирован, так как он работает так же, как "blueprint"

class SpaceObject: SKSpriteNode {

    final var atmosphere: SKSpriteNode

    init(style: SKTexture, initialVelocity: CGVector) {
        atmosphere = SKSpriteNode(texture: SKTexture(imageNamed: "atmosphere"), size: CGSize(width: 100, height: 100))
        atmosphere.zPosition = 2

        // calls the initializer
        super.init(texture: style, color: .clear, size: style.size())

        physicsBody = SKPhysicsBody(circleOfRadius: style.size().width)
        physicsBody?.velocity = initialVelocity
        physicsBody?.affectedByGravity = false
        ...

        addChild(atmosphere)
    }

    final func cleanAtmosphere() {
        atmosphere.run( ... )
    }

}

Здесь у меня есть подклассы. Они просто «заполняют» класс SpaceObject, но используют его физику и некоторые другие функции (например, cleanAtmosphere()).

final class World: SpaceObject {

    enum WorldType: String {
         case Venus, Earth, ...
    }

    var type: WorldType
    var gravity: CGFloat

    init(world: WorldType, initialVelocity: CGVector, gravity: CGFloat) {
        self.type = world
        self.gravity = gravity

        // calls the initializer
        super.init(style: SKTexture(imageNamed: "world_\(self.type)"), initialVelocity: initialVelocity)
    }

    func touchedOccurred() {
        ...
        cleanAtmosphere()
        ...
    }

}
final class Star: SpaceObject {

    enum StarType: String {
         case Sirius, Polaris, ...
    }

    var type: StarType

    init(star: StarType, initialVelocity: CGVector) {
        self.type = star

        // calls the initializer
        super.init(style: SKTexture(imageNamed: "star_\(self.type)"), initialVelocity: initialVelocity)
    }

    func explode() {
        ...
    }

}

То, что я делаю для создания объекта, просто:

let newWorld = World(world: .Venus, initialVelocity: someVector, gravity: CGFloat(8.87))

и я уверен, что в нем будет атмосфера SKSpriteNode и некоторые физические правила, действительные для каждого объекта SpaceObject.

Но ... я не уверен, что делаю это правильно Я читал, что протоколы должны обрабатывать подобные ситуации, но я до сих пор не могу понять, как. Любой намек?

1 Ответ

0 голосов
/ 26 марта 2020

Вы можете использовать наследование, чтобы делать то, что вы хотите, но протоколы также являются опцией. Преимущества протоколов в том, что структуры Swift могут использовать их, и класс может соответствовать нескольким протоколам, но может наследовать только от одного класса.

Вы упомянули правила физики. Если вы хотите использовать протокол, вы должны создать протокол для правил и включить функции, которые классы / структуры должны реализовать, чтобы соответствовать протоколу. Эта функция создаст правило.

protocol PhysicsRules {
    // Add any arguments the function takes.    
    func yourPhysicsRule()

    // Add any other physics functions you want here.
}

Тогда ваши классы World и Star соответствуют протоколу и реализуют функцию yourPhysicsRule.

final class World: SpaceObject, PhysicsRules {

   func yourPhysicsRule() {
        // Add the code to create the rule here.
    }

}

Вы можете придумать лучшие имена для протокола и функции, но это дает вам представление о том, что вы должны сделать, чтобы перейти к протоколу.

Выполнение веб-поиска для Swift protocols предоставляет множество учебных пособий по программированию, ориентированному на протокол, в том числе следующие:

Руководство для начинающих по протоколам и расширениям протоколов в Swift

Учебное пособие по программированию протоколов в Swift 5.1: Начало работы

...