В чем разница между финальным классом и классом?

final class A {

}

class B {    

}
51
Mohammad Razipour 5 Сен 2017 в 10:57

6 ответов

Лучший ответ

Final - это модификатор класса, который предотвращает его наследование или переопределение. Из яблочной документации

Вы можете предотвратить переопределение метода, свойства или индекса пометив его как окончательный . Сделайте это, написав окончательный модификатор перед методом, свойством или ключевым словом вводного индекса (например, как final var, final func, final class func и final subscript).

Любая попытка переопределить последний метод, свойство или индекс в подклассе сообщается как ошибка времени компиляции. Методы, свойства или индексы, которые вы добавляете в класс в расширении, также могут быть помечены как окончательные в определении расширения.

Вы можете пометить весь класс как финальный, написав модификатор final перед ключевым словом class в его определении класса (final class). Любая попытка создать подкласс окончательного класса сообщается как ошибка времени компиляции.

77
luckyShubhra 5 Сен 2017 в 08:38

Используйте final, когда вы знаете, что объявление не нужно переопределяется . Последнее ключевое слово является ограничением для класса, метода или свойство, указывающее, что объявление нельзя переопределить . Это позволяет компилятору безопасно исключать динамическое перенаправление отправки.

Читать далее:

https://developer.apple.com/swift/blog/?id=27

20
Vlad Khambir 5 Сен 2017 в 07:58

Окончательный означает, что никто не может наследовать от этого класса.

12
iamirzhan 5 Сен 2017 в 07:58

Кроме того, final объявление не нуждается в переопределении, также имеет лучшую производительность, чем отсутствие использования final, потому что final отключает динамическую диспетчеризацию во время выполнения, что экономит накладные расходы времени выполнения.

8
William Hu 5 Фев 2018 в 07:42

Другие ответы уже дают достаточно понимания о конечном ключевом слове. Я хочу объяснить на некотором примере.

Рассмотрим пример ниже без final ключевого слова.

class A {
   public var name: String
   var breed: String

    init(name: String, breed: String) {
        self.name = name
        self.breed = breed
    }
}
class B:A{
    override init(name: String, breed: String) {
        super.init(name: name, breed: breed)
    }
}

В приведенном выше коде это позволяет перезаписать переменную своего суперкласса. Класс с последним ключевым словом не позволяет. Смотрите ниже пример.

final class A {
   public var name: String
   var breed: String

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

class B:A{
    **//ERROR:inheritance from a final class 'A' class B**
    override init(name: String, breed: String) {
        super.init(name: name, breed: breed)
    }
}

Приведенный выше код выдаст ошибку наследования от конечного класса A, класса B .

7
Hitesh Surani 17 Дек 2018 в 08:10

Надеюсь, я смогу свести остальные ответы в этот SSCCE, который мне помог:

          open class Open {}     // Anyone can see, anything can subclass
public         class Normal {}   // Anyone can see, internal can subclass
internal       class Internal {} // Internal can see, internal can subclass
public   final class Final {}    // Anyone can see, nothing can subclass

В вашем проекте / модуле:

class SubOpen:     Open {}     // OK
class SubNormal:   Normal {}   // OK
class SubInternal: Internal {} // OK
class SubFinal:    Final {}    // Error: Can't subclass

В каком-то другом проекте / модуле:

class SubOpen:     Open {}     // OK
class SubNormal:   Normal {}   // Error: Can't subclass
class SubInternal: Internal {} // Error: `Internal` type not found
class SubFinal:    Final {}    // Error: Can't subclass
3
Ben Leggiero 2 Авг 2019 в 18:59