Is it possible for a class to explicitly invoke a method on a protocol's extension?

Gruntcakes

Suppose there is the following protocol with a default implementation of someFuncWithDefaultImplementation() provided by an extension.

Then is it possible for MyClass2 to both provide its own implementation of someFuncWithDefaultImplementation() which also invokes the default implementation of that method from the extension?

protocol MyProtocol : class {
    func someFuncWithDefaultImplementation()
    func someFunc()
    var  someInt:Int { get set }
}

extension MyProtocol {
    func someFuncWithDefaultImplementation() {
        someInt = 5
    }

    func someFunc() {
        someFuncWithDefaultImplementation()
    }
}

class MyClass :  MyProtocol {
    var someInt = 6
}

class MyClass2 : MyProtocol
{
    var someInt: Int = 4
    func someFuncWithDefaultImplementation()
    {
        // do some additional stuff
         /*** someFuncWithDefaultImplementation()  invoke MyProtocol extension implementation here ***/
    }
}


    let class1 = MyClass()
    class1.someFunc()

    let class2 = MyClass2()
    class2.someFunc()
dfrib

The following answer in the thread

describes using a nested dummy type to access the default implementation of a protocol from within a type that already has supplied its own implementation of that blueprinted method. We may extend this method to also allow actually making use of (blueprinted) properties of the MyClass2 instance, but within the call to the default implementation which MyClass2 already implements its custom version of (hence taking precedence over the default one).

We start by looking at a slightly more light weight version of your example, with a default implementation supplied for someFuncWithDefaultImplementation()

protocol MyProtocol : class {
    func someFuncWithDefaultImplementation()
    var someInt: Int { get set }
}

extension MyProtocol {
    func someFuncWithDefaultImplementation() {
        print("Called default impl. Currently, someInt = \(someInt)")
        print("Mutates someInt from within default implementation (0) ...")
        someInt = 0
    }
}

We use the non-elegant nested type solution in the custom implementation of someFuncWithDefaultImplementation() of MyClass2, to call the default implementation of the latter, but stores a reference in the Dummy instance back to the MyClass2 instance, to allow the someInt property of MyClass2 to be used in the default implementation call (for reading and writing), even if this is called from the Dummy type.

class MyClass2 : MyProtocol
{
    var someInt: Int = 42

    func someFuncWithDefaultImplementation()
    {
        // do some additional stuff ...
        print("In MyClass2 implementation, currently someInt = \(someInt)")

        /* Dummy 'MyClass2'-capturing type used to call the default
            implementation of 'MyProtocol', but with read and write 
            access to 'MyClass2':s self:s 'someInt' instance. */
        class Dummy : MyProtocol {
            unowned let myClass2: MyClass2
            init(_ myClass2: MyClass2) { self.myClass2 = myClass2 }
            var someInt: Int {
                get { return myClass2.someInt }
                set { myClass2.someInt = newValue }
            }
        }

        // call default implementation of 'someFuncWithDefaultImplementation'
        // supplying 'self' to read/write access to self.someInt.
        Dummy(self).someFuncWithDefaultImplementation()

        print("Back in MyClass2:s implementation; now someInt = \(someInt)") 
           // 0, woah, mutated in default implementation!
    }
}

let a = MyClass2()
a.someFuncWithDefaultImplementation()
/* In MyClass2 implementation, currently someInt = 42
   Called default impl. Currently, someInt = 42
   Mutates someInt from within default implementation (0) ...
   Back in MyClass2:s implementation; now someInt = 0         */

You could also choose to declare the nested Dummy outside of the function, just marking it private to make sure it cannot be accessed from outside MyClass2:

class MyClass2 : MyProtocol
{
    var someInt: Int = 42

    /* Dummy 'MyClass2'-capturing type used to call the default
       implementation of 'MyProtocol', but with read and write 
       access to 'MyClass2':s self:s 'someInt' instance. */
    private class Dummy : MyProtocol {
        unowned let myClass2: MyClass2
        init(_ myClass2: MyClass2) { self.myClass2 = myClass2 }
        var someInt: Int {
            get { return myClass2.someInt }
            set { myClass2.someInt = newValue }
        }
    }

    func someFuncWithDefaultImplementation()
    {
        // do some additional stuff ...
        print("In MyClass2 implementation, currently someInt = \(someInt)")

        // call default implementation of 'someFuncWithDefaultImplementation'
        // supplying 'self' to read/write access to self.someInt.
        Dummy(self).someFuncWithDefaultImplementation()

        print("Back in MyClass2:s implementation; now someInt = \(someInt)") 
           // 0, woah, mutated in default implementation!
    }
}

I will, however, repeat the same as the author of the linked answer: this approach is not very elegant.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Is it possible to invoke Parent class method from Child class object in Java?

Is it possible in Java to Invoke another class' main method and return to the invoking code?

invoke the extension method of a class without using static class but by using class iteslf using reflection

Swift: Is it possible to add a protocol extension to a protocol?

Invoke method in another class's try catch block

Extension of a protocol where the associatedType is class?

Protocol for class method

Invoke an extension method on a method without a explicit reference

Can you explicitly use an ancestor's virtual class method as a derived method?

Is it possible to inject into explicitly implemented method using Ninject?

Can't invoke protocol method on generic type restricted by other protocol

Always the default implementation of protocol gets called even after implementing the method in class extension in an XCTest file

How to explicitly invoke default method simply, without reflection and dynamic Proxy?

How to explicitly invoke default method from a dynamic Proxy?

How to invoke protocol extension default implementation with type constraints

Does a class which implements an interface's method (without explicitly implementing that interface) extend that specific interface?

Dynamic variable that needs to access an extension method of it's assigned class

Android, Kotlin : How to invoke MainActivity's method into sub class method in case of kotlin?

How to force inheriting class's method implementation to call base method before invoke own implantation?

is it possible to write an extension method only for List<T> where T is a class that inherits from class K

Extension of protocol with method which adds default parameter

Protocol extension method dispatch in Swift 2.0

Swift protocol extension method dispatch with superclass and subclass

Is it possible to write a "double" extension method?

Swift Class Extension Only When Conforming to Protocol

Swift extension only when conforming to Class AND protocol

Conform class extension to generic protocol function

How to set delegate in a protocol extension for a UIkit class

Calling class properties from within protocol extension