Как пометить метод `required` - PullRequest
1 голос
/ 01 февраля 2020

В swift я могу пометить инициализатор как required, так что производные классы должны его переопределить. Как я могу сделать то же самое для обычного метода экземпляра? Отмечая его как required, выдается ошибка компилятора.

class A {
  let a : Int
  required init(a:a) {
    self.a = a
  }
  // compiler error
  required func f() -> Int {
     return 2
  }
}

Единственное решение, о котором я могу подумать, - это сделать:

func f() -> Int {
  fatalError("Should always be overriden")
}

, но это неудовлетворительно, так как это проверка во время выполнения, а не во время компиляции.

Ответы [ 2 ]

2 голосов
/ 01 февраля 2020

Эта функция не существует в Swift.

Вы не можете заставить подкласс переопределить метод.

Однако ... ?

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

func f() -> Int {
    fatalError("Should always be overriden")
}

Глядя на этот метод, кажется, что вы хотите заставить подкласс реализовать (не переопределить) метод.

Абстрактный класс

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

Базовый класс + протокол

Если это то, что вы ищете, то вы можете достичь чего-то подобного в Swift.

class AnimalBase {

    let name: String

    init(name: String) {
        self.name = name
    }

}

protocol Animal: AnimalBase {
    func move()
}

Теперь, если вы попытаетесь определить класс, подобный этому

class Dog: Animal {

}

, компилятор заставит вас наследовать от AnimalBase

class Dog: AnimalBase, Animal {

}
* 1029 И, наконец, предоставить реализацию для move() метода
class Dog: AnimalBase, Animal {

    func move() {
        print("?")
    }
}
1 голос
/ 01 февраля 2020

Вы неправильно понимаете, что означает required. required не заставляет вас переопределять инициализатор, он требует, чтобы инициализатор существовал .

Инициализаторы не всегда наследуются. Например, если вы создадите новый назначенный инициализатор, то инициализаторы суперкласса не будут наследоваться. required инициализатор заставляет вас определить его в этом случае.

Этого не может случиться с обычными методами, потому что они всегда наследуются. Вот почему required для методов не существует.

Вы ищете абстрактный (или чисто виртуальный в C ++) метод, который является концепцией, которая не существует в Свифте.

...