Swift4.2语言规范(十五) 继承
类可以从另一个类继承方法,属性和其他特性。当一个类继承自另一个类时,继承类称为子类,它继承的类称为其超类。继承是一种基本行为,它将类与Swift中的其他类型区分开来。 Swift中的类可以调用和访问属于其超类的方法,属性和下标,并可以提供这些方法,属性和下标的自己的重写版本,以优化或修改它们的行为。Swift通过检查覆盖定义是否具有匹配的超类定义来帮助确保覆盖是正确的。 类还可以将属性观察器添加到继承的属性,以便在属性值更改时得到通知。属性观察器可以添加到任何属性,无论它最初是被定义为存储属性还是计算属性。 定义基类任何不从其他类继承的类都称为基类。 注意 Swift类不从通用基类继承。您定义的类而不指定超类会自动成为您构建的基类。 下面的示例定义了一个名为的基类 所述 1 class Vehicle { 2 var currentSpeed = 0.0 3 var description: String { 4 return "traveling at (currentSpeed) miles per hour" 5 } 6 func makeNoise() { 7 // do nothing - an arbitrary vehicle doesn‘t necessarily make a noise 8 } 9 } 您 let someVehicle = Vehicle() 创建新 1 print("Vehicle: (someVehicle.description)") 2 // Vehicle: traveling at 0.0 miles per hour 在 子类子类化是在现有类上创建新类的行为。子类继承现有类的特征,然后可以对其进行细化。您还可以向子类添加新特征。 要指示子类具有超类,请在超类名称之前写入子类名称,用冒号分隔: 1 class SomeSubclass: SomeSuperclass { 2 // subclass definition goes here 3 } 以下示例定义了一个名为的子类 1 class Bicycle: Vehicle { 2 var hasBasket = false 3 } 新的 除了它继承的特性之外, 默认情况下, 1 let bicycle = Bicycle() 2 bicycle.hasBasket = true 您还可以修改继承的 1 bicycle.currentSpeed = 15.0 2 print("Bicycle: (bicycle.description)") 3 // Bicycle: traveling at 15.0 miles per hour 子类本身可以是子类。下一个例子 1 class Tandem: Bicycle { 2 var currentNumberOfPassengers = 0 3 }
如果您创建了一个实例 1 let tandem = Tandem() 2 tandem.hasBasket = true 3 tandem.currentNumberOfPassengers = 2 4 tandem.currentSpeed = 22.0 5 print("Tandem: (tandem.description)") 6 // Tandem: traveling at 22.0 miles per hour 重写子类可以提供自己的实例方法,类型方法,实例属性,类型属性或下标的自定义实现,否则它将从超类继承。这被称为重写。 要覆盖否则将继承的特性,请使用 该 访问超类方法,属性和下标当您为子类提供方法,属性或下标覆盖时,将现有超类实现用作覆盖的一部分有时很有用。例如,您可以优化现有实现的行为,或将修改后的值存储在现有的继承变量中。 如果这是合适的,您可以使用
重写方法您可以覆盖继承的实例或类型方法,以在子类中提供方法的定制或替代实现。 以下示例定义了一个新的 1 class Train: Vehicle { 2 override func makeNoise() { 3 print("Choo Choo") 4 } 5 } 如果您创建一个新实例 1 let train = Train() 2 train.makeNoise() 3 // Prints "Choo Choo" 覆盖属性您可以覆盖继承的实例或类型属性,以便为该属性提供自己的自定义getter和setter,或添加属性观察器以使覆盖属性能够在基础属性值更改时进行观察。 覆盖属性getter和setter您可以提供自定义getter(和setter,如果适用)以覆盖任何继承的属性,无论继承的属性是在源上实现为存储属性还是计算属性。子类不知道继承属性的存储或计算性质 - 它只知道继承的属性具有特定的名称和类型。您必须始终声明要覆盖的属性的名称和类型,以使编译器能够检查您的覆盖是否与具有相同名称和类型的超类属性匹配。 通过在子类属性覆盖中提供getter和setter,可以将继承的只读属性作为读写属性提供。但是,您不能将继承的读写属性显示为只读属性。 注意 如果您将setter作为属性覆盖的一部分提供,则还必须为该覆盖提供getter。如果您不想在重写getter中修改继承属性的值,则可以通过 以下示例定义了一个名为的新类 1 class Car: Vehicle { 2 var gear = 1 3 override var description: String { 4 return super.description + " in gear (gear)" 5 } 6 }
如果你创建的实例 1 let car = Car() 2 car.currentSpeed = 25.0 3 car.gear = 3 4 print("Car: (car.description)") 5 // Car: traveling at 25.0 miles per hour in gear 3 覆盖属性观察器您可以使用属性覆盖将属性观察器添加到继承的属性。这使您可以在继承属性的值更改时收到通知,无论该属性最初如何实现。有关属性观察器的更多信息,请参阅Property Observers。 注意 您不能将属性观察器添加到继承的常量存储属性或继承的只读计算属性。无法设置这些属性的值,因此不适合将提供 另请注意,您不能同时为同一属性提供重写setter和覆盖属性观察器。如果要观察属性值的更改,并且您已经为该属性提供了自定义setter,则只需观察自定义setter中的任何值更改即可。 以下示例定义了一个名为的新类 1 class AutomaticCar: Car { 2 override var currentSpeed: Double { 3 didSet { 4 gear = Int(currentSpeed / 10.0) + 1 5 } 6 } 7 } 当你设置 1 let automatic = AutomaticCar() 2 automatic.currentSpeed = 35.0 3 print("AutomaticCar: (automatic.description)") 4 // AutomaticCar: traveling at 35.0 miles per hour in gear 4 防止覆盖您可以通过将方法,属性或下标标记为final来阻止它被覆盖。通过写做到这一点 任何覆盖子类中的最终方法,属性或下标的尝试都会报告为编译时错误。您添加到扩展中的类的方法,属性或下标也可以在扩展的定义中标记为final。 您可以通过在类定义(final?class)中的 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |