Design patterns 共享方法的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

Swift中没有抽象类

人们有其他方法来拥有类似的机制。但他们没有回答我的问题。如何用一些相同的函数和一些不同的函数构建一系列类

建议我们使用协议而不是抽象基类。但是,协议不是一个我们可以编写函数体的地方,所以对于每个子类中的相同函数,我们必须编写与子类编号相同的函数体

我想要的是这样的东西:

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:)