斯威夫特 - 混合抽象和具体方法

时间:2015-06-01 13:12:21

标签: ios swift oop abstract-class

Swift没有抽象的类和方法。相反,它提供协议。

当你的课程完全抽象或完全具体时,这很好。

但是什么是最好的'斯威夫特'如何实现一个也有具体方法的抽象类?

伪代码示例:

class Animal {
  abstract makeSound()
  abstract eyeCount()
}

class Mammal : Animal {
  override eyeCount { return 2 } // Let's assume all mammals have hard-coded 2 eyes...

class Cat : Mammal {
  override makeSound { print "Meow!" }
}

class Dog : Mammal {
  override makeSound { print "Woof!" }
}

在哺乳动物中,我确实想要实施具体的方法eyeCount(),因为所有哺乳动物都有2个硬编码的眼睛(据说是),我不想在狗和猫中重新实施它。但是,makeSound()只能用于狗和猫,因为哺乳动物的声音各不相同。

你如何在Swift中实现它?谢谢!

4 个答案:

答案 0 :(得分:5)

我会像这样实现它:

class AbstractAnimal
{
    // Fully abstract method
    func methodThatReturnsSomething() -> String  {
        fatalError("methodThatReturnsSomething() is abstract and must be overriden!");
    }

    func eyeCount() -> Int {
        return 2;
    }
}

fatalError阻止Xcode抱怨抽象方法methodThatReturnsSomething()实际上没有返回任何内容。

答案 1 :(得分:5)

您可以使用协议扩展来获得与抽象类完全相同的行为:检查抽象方法是否在编译时在子类中实现。

protocol Entity {
  // MARK: - Abstract methods
  func filename() -> String

  // MARK: - Traits
  func saveData(data: NSArray)
}

extension Entity {
  func saveData(data: NSArray) {
      // Do something and call:
      let filename = filename()
  }
}

现在,您可以在子类上实现Entity协议,编译器将强制您在已实现filename()方法时实施saveData()。< / p>

答案 2 :(得分:0)

执行此操作的常用方法是使用具有其中具体方法的抽象类。所有类都可以继承此抽象类,以继承具体方法和抽象方法。

UIGuestureRecognizerUIGuestureRecognizerSubclass就是一个非常好的例子。因为这是用于子类化,所以这个抽象类包含许多内部具体方法以及可实现的子类可抽象方法。

这是许多Swift和Objective-C项目的常见模式。

答案 3 :(得分:0)

@BobDickinson在Abstract functions in Swift Language中建议的一种方法是:

protocol Animal {
    var eyeCount: Int { get }
    func makeSound()
}

// Note - `Mammal` doesn't conform to `Animal`.
class Mammal {
    let eyeCount = 2
}

// Only `Cat` and `Dog` conform to `Animal`, so only they need to implement `makeSound`.
class Dog: Mammal, Animal {
    func makeSound() {
        println("Woof")
    }
}

class Cat: Mammal, Animal {
    func makeSound() {
        println("Meow")
    }
}