Eric33187
Eric33187

Reputation: 1156

How to implement custom implementation of method?

I'm drawing a blank for some reason.. If I want to make a bunch of objects from a class, but I want each instance to have its own unique implementation of a certain method, how would I do this?

For example:

class MyClass {
    var name: String
    
    func doSomething() { 
        // Each object would have custom implementation of this method, here.
    }
}

Do I provide each object with its own closure during initialization, and then call that closure in the doSomething() method? I'm trying to figure out the correct or "Swiftly" way to do this. I'm also thinking along the lines of something with protocols, but I can't seem to figure out how to go about this.

Upvotes: 0

Views: 278

Answers (2)

matt
matt

Reputation: 535801

Do I provide each object with its own closure during initialization, and then call that closure in the doSomething() method

Yes. That is extremely common and eminently Swifty. Incredibly miminalistic example:

struct S {
    let f:()->()
    func doYourThing() { f() }
}
let s = S { print("hello") }
let s2 = S { print("goodbye" )}
s.doYourThing() // hello
s2.doYourThing() // goodbye

Giving an object a settable method instance property is very, very easy and common. It doesn't have to be provided during initialization — you might set this property later on, and a lot of built-in objects work that way too.

That, after all, is all you're doing when you create a data task with dataTask(with:completionHandler:). You are creating a data task and handing it a function which it stores, and which it will call when it has performed the actual networking.

Upvotes: 0

timbre timbre
timbre timbre

Reputation: 13996

I think there're many ways to do it.

In case of Base class + some sub-classes (e.g. Animal, subclassed by Dog, Cat, etc), you can do this:

First of all it's a good idea to define a protocol:

protocol MyProtocol {
   func doSomething()
}

Also provide a default implementation, which throws a fatal error if a class doesn't override that method:

extension MyProtocol {
    func doSomething() {
        fatalError("You must override me")
    }
}

Now your base class confirms the protocol thanks to default implementation. But it will throw a fatal error at runtime:

class MyClass: MyProtocol {
    // conformant
}

Child class, however, will run correctly as long as it overrides this function:

class MyOtherClass: MyClass {

    func doSomething() {
        print("Doing it!")
    }
}

You could also move fatal error into base class, and not do any extension implementation.

In case of many instances of the same Class, that solution makes no sense. You can use a very simple callback design:

typealias MyDelegate = () -> Void

class MyClass {

    var delegate: MyDelegate?

    func doSomething() {
        delegate?()
    }
}

let x = MyClass()
x.delegate = {
    print("do it!")
}
x.doSomething()

// Or you can use a defined function
func doIt() {
    print("also doing it")
}
x.delegate = doIt
x.doSomething()

It can also be that you re looking for Strategy pattern, or Template pattern. Depends on your usage details.

Upvotes: 1

Related Questions