Swift:覆盖对象方法

时间:2015-02-23 16:59:26

标签: swift

我定义了一个类:

class Person {
    func speak(phrase: String) {
        NSLog("\(phrase)")
    }
}

假设我想要更改speak方法的行为。在java中,我会覆盖此方法:

Person p = new Person() {
    @Override
    public void speak(String phrase) {
        // Do something different
    }
};

如何覆盖Swift中的方法?我尝试了以下无济于事:

let person = Person()
person.speak = { (String) -> () in
    // Do something different
}

错误:Cannot assign to 'speak' in 'person'

我知道我可以设置一个变量来改变行为或子类Person,但我想到了一个不同的用例,需要这样的东西。使用这个例子更容易解释。

1 个答案:

答案 0 :(得分:4)

你不能在Swift中以这种方式创建匿名类,而是必须派生一个新类:

class AnotherPerson: Person {
    override func speak(phrase: String) {
        NSLog("\(phrase) overidden!")
    }
}

最接近覆盖特定方法的匿名实例化是使speak成为函数属性:

class Person {
    var speak: (String)->() = { (phrase: String) in
        println(phrase)
    }
}

let person = Person()
person.speak("Frank")  // => Frank
person.speak = { (phrase: String) in println("Hi, \(phrase)") }
person.speak("Frank")  // => Hi, Frank

如果您不希望随机消费者能够修改speak,您可以通过初始化程序将其设置为let属性:

class Person {
    let speak: (String)->()

    init(speaker: (String)->() = println) {
        speak = speaker
    }
}

Person().speak("Frank")  // => Frank
Person({ println("Hi, \($0)") }).speak("Frank")  // => Hi, Frank

let person = Person()
person.speak = { println($0) }  // error: cannot assign to speak

这里我们将默认值设置为println,从而保留原始默认行为。