Design patterns 共享方法的swift抽象类
Swift中没有抽象类 人们有其他方法来拥有类似的机制。但他们没有回答我的问题。如何用一些相同的函数和一些不同的函数构建一系列类 建议我们使用协议而不是抽象基类。但是,协议不是一个我们可以编写函数体的地方,所以对于每个子类中的相同函数,我们必须编写与子类编号相同的函数体 我想要的是这样的东西:Design patterns 共享方法的swift抽象类,design-patterns,swift,abstract-class,virtual-functions,Design Patterns,Swift,Abstract Class,Virtual Functions,Swift中没有抽象类 人们有其他方法来拥有类似的机制。但他们没有回答我的问题。如何用一些相同的函数和一些不同的函数构建一系列类 建议我们使用协议而不是抽象基类。但是,协议不是一个我们可以编写函数体的地方,所以对于每个子类中的相同函数,我们必须编写与子类编号相同的函数体 我想要的是这样的东西: protocol Animal : class { func run() var legs : [Leg] { get } // this method is invalid i
protocol Animal : class {
func run()
var legs : [Leg] { get }
// this method is invalid in swift protocol
// as protocol methods must have no bodies.
// Instead, the same method will be repeated
// in every subclasses
func legCount() -> Int {
return self.legs.count
}
}
class Dog : Animal {
func run() {}
var legs : [Leg]
}
class Bird : Animal {
func run() {}
var legs : [Leg]
}
struct Leg { } // Just so it'll run in a Playground
protocol AnimalType: class {
func run()
var legs : [Leg] { get }
func legCount() -> Int
}
class Animal: AnimalType {
func run() {
fatalError("run() can not be called on the Animal class")
}
var _legs: [Leg]! = nil
var legs: [Leg] { get { return _legs } }
func legCount() -> Int {
return legs.count
}
}
class Dog: Animal {
override func run() {
println("Running Dog!")
}
override init() {
super.init()
_legs = [Leg](count: 4, repeatedValue: Leg())
}
}
class Bird : Animal {
override func run() {
println("Running Bird!")
}
override init() {
super.init()
_legs = [Leg](count: 2, repeatedValue: Leg())
}
}
我有一种方法可以做到:
协议动物类型
。在这本书中,定义动物是什么,它能做什么,但不是它如何做任何事情。此命名约定在Swift标准库中广泛使用:CollectionType
、SequenceType
、IntegerType
、BooleanType
,等等类动物
,该类动物定义了所有动物如何做它们共同拥有的事情;对于其他所有内容,只需创建占位符函数或属性(这是您的“抽象”类)。如果有一个函数调用抽象类没有意义,请调用它的主体类狗
、类鸟
等,并根据需要覆盖功能和/或添加新功能protocol Animal : class {
func run()
var legs : [Leg] { get }
// this method is invalid in swift protocol
// as protocol methods must have no bodies.
// Instead, the same method will be repeated
// in every subclasses
func legCount() -> Int {
return self.legs.count
}
}
class Dog : Animal {
func run() {}
var legs : [Leg]
}
class Bird : Animal {
func run() {}
var legs : [Leg]
}
struct Leg { } // Just so it'll run in a Playground
protocol AnimalType: class {
func run()
var legs : [Leg] { get }
func legCount() -> Int
}
class Animal: AnimalType {
func run() {
fatalError("run() can not be called on the Animal class")
}
var _legs: [Leg]! = nil
var legs: [Leg] { get { return _legs } }
func legCount() -> Int {
return legs.count
}
}
class Dog: Animal {
override func run() {
println("Running Dog!")
}
override init() {
super.init()
_legs = [Leg](count: 4, repeatedValue: Leg())
}
}
class Bird : Animal {
override func run() {
println("Running Bird!")
}
override init() {
super.init()
_legs = [Leg](count: 2, repeatedValue: Leg())
}
}
然后,如果需要说出动物的数组
,请使用协议声明数组,而不是动物
类:
let animals: Array<AnimalType>
这将输出:
Dogs have 4 legs.
Running Dog!
Birds have 2 legs.
Running Bird!
阵列也可以工作:
var animals: Array<AnimalType> = [dog, bird]
var legs = animals.map { $0.legCount() }
println(legs)
对其调用run()
将是一个致命错误:
a.run()
致命错误:无法对动物类:文件第18行调用run()
拥有AnimalType
协议有什么好处?也就是说,你可以使用让动物:[Animal]=…
,我认为你不会因此失去任何东西。@AaronBrager没错,[Animal]
会很好地工作。一般来说,我认为它允许实现相同协议的不同基类。但在这种情况下,拥有它可能没有多大意义。类greatcrystalineentity:AnimalType{func legCount()->Int{fatalError(“水晶实体没有腿”)}
@AaronBrager nice:)