4

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.

1 Answer 1

4

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.

Sign up to request clarification or add additional context in comments.

1 Comment

edits: included the use of function properties to emulate what was wanted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.