定义一个父类
Any class that does not inherit from another class is known as a base class.
不继承其他类的类称为父类。
The example below defines a base class called Vehicle. This base class defines a stored property called currentSpeed, with a default value of 0.0 (inferring a property type of Double). The currentSpeed property’s value is used by a read-only computed String property called description to create a description of the vehicle.
下面的例子定义了一个父类Vehicle。这个父类定义了一个存储属性currentSpeed,默认值为0.0(类型为double)。属性currentSpeed的值被一个只读的string属性description调用来创建vehicle的描述。
The Vehicle base class also defines a method called makeNoise. This method does not actually do anything for a base Vehicle instance, but will be customized by subclasses of Vehicle later on:
基类Vehicle还定义了一个方法makeNoise。这个方法什么都不做,但是会由后面的子类定制:
class Vehicle {
var currentSpeed = 0.0
var description: String {
return "traveling at \(currentSpeed) miles per hour"
}
func makeNoise() {
// do nothing - an arbitrary vehicle doesn't necessarily make a noise
}
}
创建一个Vehicle实例
let someVehicle = Vehicle()
Having created a new Vehicle instance, you can access its description property to print a human-readable description of the vehicle’s current speed:
创建了新的Vehicle实例,你就可以获取它的description属性来打印一个vehicle的当前速度的描述:
print("Vehicle: \(someVehicle.description)")
// Vehicle: traveling at 0.0 miles per hour
创建子类(Subclassing)
Subclassing is the act of basing a new class on an existing class. The subclass inherits characteristics from the existing class, which you can then refine. You can also add new characteristics to the subclass.
创建子类就是基于已有的类创建一个新类的行为。子类从已有的类继承属性—你可以重定义这些属性。你也可以给子类添加新的属性。
To indicate that a subclass has a superclass, write the subclass name before the superclass name, separated by a colon:
想表明一个子类拥有一个父类,只需在子类名字后面写上父类名字,以冒号隔开:
class SomeSubclass: SomeSuperclass {
// subclass definition goes here
}
下面的例子创建一个子类Bicycle,继承自Vehicle
class Bicycle: Vehicle {
var hasBasket = false
}
The new Bicycle class automatically gains all of the characteristics of Vehicle, such as its currentSpeed and description properties and its makeNoise() method.
新的Bicycle类自动获得Vehicle的所有属性,比如currentSpeed和description属性,以及makeNoise()方法。
In addition to the characteristics it inherits, the Bicycle class defines a new stored property, hasBasket, with a default value of false (inferring a type of Bool for the property).
除了继承来的属性之外,Bicycle类还定义了一个新的存储属性hasBasket,默认值为false(类型为bool).
By default, any new Bicycle instance you create will not have a basket. You can set the hasBasket property to true for a particular Bicycle instance after that instance is created:
你创建的任何Bicycle实例默认都没有框(basket).你可以在一个Bicycle实例被创建后,为这个实例设置hasBasket属性为true:
let bicycle = Bicycle()
bicycle.hasBasket = true
You can also modify the inherited currentSpeed property of a Bicycle instance, and query the instance’s inherited description property:
你也可以修改Bicycle实例继承来的currentSpeed属性,并请求该实例继承来的description属性:
bicycle.currentSpeed = 15.0
print("Bicycle: \(bicycle.description)")
// Bicycle: traveling at 15.0 miles per hour
Subclasses can themselves be subclassed. The next example creates a subclass of Bicycle for a two-seater bicycle known as a “tandem”:
子类也可以被继承。下一个例子创建了一个Bicycle的子类,tandem:
class Tandem: Bicycle {
var currentNumberOfPassengers = 0
}
Tandem inherits all of the properties and methods from Bicycle, which in turn inherits all of the properties and methods from Vehicle. The Tandem subclass also adds a new stored property called currentNumberOfPassengers, with a default value of 0.
Tandem继承了Bicycle的所有属性和方法,包括Bicycle从Vehicle继承的属性和方法。Tandem子类也添加了一个新的存储属性currentNumberOfPassengers,默认值为0。
If you create an instance of Tandem, you can work with any of its new and inherited properties, and query the read-only description property it inherits from Vehicle:
如果你创建了一个Tandem实例,你就可以使用它的或新的或继承来的属性,以及请求从Vehicle继承来的只读的description属性:
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
重写
To override a characteristic that would otherwise be inherited, you prefix your overriding definition with the override keyword. Doing so clarifies that you intend to provide an override and have not provided a matching definition by mistake. Overriding by accident can cause unexpected behavior, and any overrides without the override keyword are diagnosed as an error when your code is compiled.
重写一个特性,只需要在重写前加上override关键字。这么做表示你提供一个重写。错误地重写会导致意外的行为发生,而且没有override关键字的重写会在编译时诊断为错误。
获取父类方法,属性和下标脚本
When you provide a method, property, or subscript override for a subclass, it is sometimes useful to use the existing superclass implementation as part of your override. For example, you can refine the behavior of that existing implementation, or store a modified value in an existing inherited variable.
当你在一个子类中重写一个方法,属性或下标脚本时,有时候需要使用父类的实现。比如,你可以重新定义已有实现的行为,或者在已有的继承的变量上存储一个修改值。
Where this is appropriate, you access the superclass version of a method, property, or subscript by using the super prefix:
An overridden method named someMethod() can call the superclass version of someMethod() by calling super.someMethod() within the overriding method implementation.
An overridden property called someProperty can access the superclass version of someProperty as super.someProperty within the overriding getter or setter implementation.
An overridden subscript for someIndex can access the superclass version of the same subscript as super[someIndex] from within the overriding subscript implementation.
在下面的情况中,你可以使用super 前缀来调用父类的方法,属性或是下标脚本:
某个重写的方法someMethod()可以获取父类的someMethod()方法,只需在重写方法中调用super.someMethod()。
某个重写的属性someProperty可以获取父类的someProperty属性,只需在重写的getter或setter实现中调用
super.someProperty 。
一个重写的下标脚本someIndex可以获取父类的someIndex下标脚本,只需在重写的下标脚本实现中调用super[someIndex]。
重写方法
You can override an inherited instance or type method to provide a tailored or alternative implementation of the method within your subclass.
你可以在你的子类中重写一个继承的实例或类型方法。
The following example defines a new subclass of Vehicle called Train, which overrides the makeNoise() method that Train inherits from Vehicle:
下面的例子定义了一个新的Vehicle子类,Train,此子类重写了makeNoise() 方法:
class Train: Vehicle {
override func makeNoise() {
print("Choo Choo")
}
}
If you create a new instance of Train and call its makeNoise() method, you can see that the Train subclass version of the method is called:
如果你创建了一个Train的新的实例,并调用它的makeNoise()方法,你可以看到调用的是Train子类的方法实现:
let train = Train()
train.makeNoise()
// Prints "Choo Choo"
重写属性
You can override an inherited instance or type property to provide your own custom getter and setter for that property, or to add property observers to enable the overriding property to observe when the underlying property value changes.
你可以重写继承的实例或类型属性,为此属性提供自己的getter和setter,或添加新的属性观察器
-
重写属性的getter和setter
You can provide a custom getter (and setter, if appropriate) to override any inherited property, regardless of whether the inherited property is implemented as a stored or computed property at source. The stored or computed nature of an inherited property is not known by a subclass—it only knows that the inherited property has a certain name and type. You must always state both the name and the type of the property you are overriding, to enable the compiler to check that your override matches a superclass property with the same name and type.
你可以提供自定义的getter(或者setter)来重写继承的属性,无论此属性一开始是一个存储属性还是一个计算属性。子类并不知道继承的存储属性或计算属性具体是什么,它只知道继承的属性的名字和类型。你必须声明你要重写的属性的名字和类型,让编译器可以检查你的重写和父类的属性的名字和类型是匹配的。
You can present an inherited read-only property as a read-write property by providing both a getter and a setter in your subclass property override. You cannot, however, present an inherited read-write property as a read-only property.
你可以把一个继承的只读属性改为读写属性,只需在你的子类属性的重写中提供getter和setter。然而,你不能把一个继承的读写属性改为只读属性。
The following example defines a new class called Car, which is a subclass of Vehicle. The Car class introduces a new stored property called gear, with a default integer value of 1. The Car class also overrides the description property it inherits from Vehicle, to provide a custom description that includes the current gear:
下面的例子定义了一个新的类Car,它是Vehicle的子类。Car类引入了一个新的存储属性gear,默认值为 1.Car类还重写了它从Vehicle继承来的description属性:
class Car: Vehicle { var gear = 1 override var description: String { return super.description + " in gear \(gear)" } }
The override of the description property starts by calling super.description, which returns the Vehicle class’s description property. The Car class’s version of description then adds some extra text onto the end of this description to provide information about the current gear.
description属性的重写由调用super.description开始,这返回了Vehicle类的description属性。Car类的description接着在后面加上类些额外的文本,来表示当前gear的信息。
If you create an instance of the Car class and set its gear and currentSpeed properties, you can see that its description property returns the tailored description defined within the Car class:
如果你创建了一个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
-
重写属性观察者
You can use property overriding to add property observers to an inherited property. This enables you to be notified when the value of an inherited property changes, regardless of how that property was originally implemented. For more information on property observers, see Property Observers.
你可以使用属性重写来给继承的属性添加属性观察者。这使得这个继承的属性的值改变时,会向你发送通知,不管那个属性的原始实现是什么。
The following example defines a new class called AutomaticCar, which is a subclass of Car. The AutomaticCar class represents a car with an automatic gearbox, which automatically selects an appropriate gear to use based on the current speed:
下面的例子定义了一个新类AutomaticCar,它是Car的一个子类。AutomaticCar类表示一辆拥有自动变速器(automatic gearbox)的车:
class AutomaticCar: Car { override var currentSpeed: Double { didSet { gear = Int(currentSpeed / 10.0) + 1 } } }
Whenever you set the currentSpeed property of an AutomaticCar instance, the property’s didSet observer sets the instance’s gear property to an appropriate choice of gear for the new speed. Specifically, the property observer chooses a gear that is the new currentSpeed value divided by 10, rounded down to the nearest integer, plus 1. A speed of 35.0 produces a gear of 4:
无论你何时设置AutomaticCar实例的currentSpeed属性,此属性的didSet观察者都会把此实例等gear属性设为一个合适的值。
let automatic = AutomaticCar() automatic.currentSpeed = 35.0 print("AutomaticCar: \(automatic.description)") // AutomaticCar: traveling at 35.0 miles per hour in gear 4
防止重写
You can prevent a method, property, or subscript from being overridden by marking it as final. Do this by writing the final modifier before the method, property, or subscript’s introducer keyword (such as final var, final func, final class func, and final subscript).
你可以把方法,属性,订阅标记为final从而防止被重写。比如:final var, final func, final class func, and final subscript
You can mark an entire class as final by writing the final modifier before the class keyword in its class definition (final class). Any attempt to subclass a final class is reported as a compile-time error.
你可以把整个类标记为final,只需要在class定义前加上final关键字,如 final class。
继承一个final类会报编译时错误。
如果你觉得文章不错,可以给我打赏点比特股(bts),以示支持。_
BTS6jUaVVkz9gN8t9sWY9NR5UbiubSz7QtVDnEtFGpujYeqQSfQ5E
网友评论