Reputation: 10699
I'm defining a class:
class Person {
func speak(phrase: String) {
NSLog("\(phrase)")
}
}
Suppose that I want to change the behavior of the speak
method. In java I would override this method:
Person p = new Person() {
@Override
public void speak(String phrase) {
// Do something different
}
};
How can I override the method in Swift? I tried the following to no avail:
let person = Person()
person.speak = { (String) -> () in
// Do something different
}
Error: Cannot assign to 'speak' in 'person'
I know I could set a variable to change the behavior or subclass Person, but I'm thinking of a different use case where something like this is needed. Using this example was easier to explain.
Upvotes: 4
Views: 1636
Reputation: 26883
You cannot create anonymous classes in this manner in Swift, instead you must derive a new class:
class AnotherPerson: Person {
override func speak(phrase: String) {
NSLog("\(phrase) overidden!")
}
}
The closest to anonymous instantiations that override particular methods is to make speak
a function property:
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
If you don’t want random consumers to be able to modify speak
, you can make it a let
property set via the initializer:
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
Here we set the default to println
which thus preserves the original default behavior.
Upvotes: 4