Vehicle
. Этот базовый класс определяет хранимое свойство с названием currentSpeed
и предопределенным значением 0.0 (что выведет тип свойства в Double
). Значение свойства currentSpeed
используется вычисляемым свойством только-для-чтения типа String
с названием description
для создания описания транспорта.
Vehicle
также определяет метод с названием makeNoise
. Этот метод не делает ничего фактически для объекта базового типа Vehicle
, но он может быть кастомизирован впоследствии подклассами класса Vehicle
:
class Vehicle {
var currentSpeed = 0.0
var description: String {
return "traveling at \(currentSpeed) miles per hour"
}
func makeNoise() {
// не делает ничего - абстрактный транспорт не может издавать звуков
}
}
Vehicle
с помощью синтаксиса конструктора, который записывается в качестве имени типа, сопровождаемого пустыми круглыми скобками:
let someVehicle = Vehicle()
Vehicle
, Вы можете получить доступ к его свойству desctiption
для распечатки его человокопонятного описания с текущей скоростью транспорта:
print("Vehicle: \(someVehicle.description)")
// Vehicle: traveling at 0.0 miles per hour
Класс Vehicle
определяет общие характеристики для абстрактного транспорта, но сам по себе он неособо используем. Чтобы сделать его более полезным, Вам нужно заменить его для описания более конкретных типов транспорта.
class SomeSuperclass {}
class SomeSubclass: SomeSuperclass {
// здесь идёт определение подкласса
}
Bicycle
с надклассовом Vehicle
:
class Bicycle: Vehicle {
var hasBasket = false
}
Новый класс Bicycle
автоматически получает все характеристики класса Vehicle
, как например свойства currentSpeed
и description
и метод makeNoise()
.
Bicycle
определяет новое хранимое свойство, hasBasket
, со значением по-умолчанию false
(выводящее тип этого свойства в Bool
).
Bicycle
, который Вы создаёте, не будет иметь корзины. Вы можете установить свойство hasBasket
в значение true для отдельного объекта типа Bicycle
после создания объекта:
let bicycle = Bicycle()
bicycle.hasBasket = true
currentSpeed
объекта типа Bicycle
и запросить унаследованное свойство description
:
bicycle.currentSpeed = 15.0
print("Bicycle: \(bicycle.description)")
// Bicycle: traveling at 15.0 miles per hour
Bicycle
для двухместного велосипеда под названием "тандем":
class Tandem: Bicycle {
var currentNumberOfPassengers = 0
}
Tandem наследует все свойства и методы у Bicycle
, который в свою очередь наследует все свойства и методы у Vehicle
. Подкласс Tandem
также добавляет новое хранимое свойство currentNumberOfPassengers
со значением по-умолчанию 0.
Tandem
, Вы можете работать с любым из его новых или унаследованных свойств и запрашивать свойство только-для-чтения description
, которое он наследует у Vehicle
:
let tandem = Tandem()
tandem.hasBasket = true
tandem.currentNumberOfPassengers = 2
tandem.currentSpeed = 22.0
print("Tandem: \(tandem.description)")
// Tandem: traveling at 22.0 miles per hour
override
. Когда Вы так делаете, Вы подтверждаете своё намерение предоставить перезапись, а не случайное совпадения определения по ошибке. Перезапись по ошибке может вызвать неожиданное поведение, поэтому любые перезаписи без ключевого слова override
будут диагностированы в качестве ошибки в процессе сборки Вашего кода.
override
также указывает компилятору Swift проверить, что Вы перезаписываете надкласс (или одного из его родителей), который имеет объявление, которое совпадает с тем, что Вы предоставляете на перезапись. Эта проверка гарантирует, что Ваше перезаписывающее определение корректно.
super
:
class
для разрешения подклассам перезаписывать реализации суперклассом этого метода.
Vehicle
с названием Train
, который перезаписывает метод makeNoise()
, наследуемый классом Train
от Vehicle
:
class Train: Vehicle {
override func makeNoise() {
print("Choo Choo")
}
}
Train
и вызовите его метод makeNoise()
, Вы сможете увидеть, что версия этого метода подкласса Train
вызывается:
let train = Train()
train.makeNoise()
// Выведет "Choo Choo"
class
для того, чтобы позволить подклассу перезаписать реализацию суперкласса.
super.someProperty
из геттера, где someProperty
это название перезаписываемого Вами свойства.
Car
, который является подклассом Vehicle
. Класс Car
представляет новое хранимое свойство с названием gear
со значением по-умолчанию 1. Класс Car
также перезаписыаает свойство description
, наследуемое им от Vehicle
, для предоставления собственного описания, включающее текущую передачу:
class Car: Vehicle {
var gear = 1
override var description: String {
return super.description + " in gear \(gear)"
}
}
Перезапись свойства description
начинается с вызова super.description
, которое возвращает свойство description
класса Vehicle
. Версия свойства description
класса Car
добавляет дополнительный текст в конец описания для предоставления информации о текущей передачи.
Car
и установите его значения gear
и currentSpeed
, то Вы сможете увидеть, что его свойство description
возвращает описание, заданное в классе Car
:
let car = Car()
car.currentSpeed = 25.0
car.gear = 3
print("Car: \(car.description)")
// Car: traveling at 25.0 miles per hour in gear 3
willSet
и didSet
в качестве части реализации перезаписи.
AutomaticCar
, который является подклассом Car
. Класс AutomaticCar
репрезентует машину с автоматической коробкой передач, которая автоматически выбирает подходящую передачу на основе текущей скорости:
class AutomaticCar: Car {
override var currentSpeed: Double {
didSet {
gear = Int(currentSpeed / 10.0) + 1
}
}
}
currentSpeed
объекта AutomaticCar
, то наблюдатель свойства didSet
устанавливает значения свойства gear
в подходящее значении на основании новой скорости. Точнее говоря, наблюдатель свойства выбирает новое, равное новому значению currentSpeed
, делённому на 10, округлённому вниз до ближайшего целого, и увеличенного 1. Скорость 35.0 выдают в результате передачу 4:
let automatic = AutomaticCar()
automatic.currentSpeed = 35.0
print("AutomaticCar: \(automatic.description)")
// AutomaticCar: traveling at 35.0 miles per hour in gear 4
final
перед методом, свойством или сабскриптом (как например final var
, final func
, final class func
или final subscript
.
final
перед ключевым словом class
в определении класса (final class)
. Любые попытки унаследовать финальный класс будут помечены как ошибки времени компиляции.