Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Inheritance: Super's Super

Supposing to have this three classes with this simply hierarchy:

class A {
    func foo() {
       print("A")
    }
}

class B: A {
    override func foo() {
       super.foo()
       print("B")
    }
}

class C: B {
    override func foo() {
       // *******
       print("C")
    }
}

In class C, in overrided method foo I want to call a method foo: is it possible?

In C++ this can be achieved with C->A::foo(), but how do I do this in Swift?

like image 280
Luca Davanzo Avatar asked Mar 08 '16 15:03

Luca Davanzo


People also ask

What is inheritance Swift?

Inheritance allows us to create a new class from an existing class. The new class that is created is known as subclass (child or derived class) and the existing class from which the child class is derived is known as superclass (parent or base class). Swift Inheritance Syntax.

Which inheritance is not supported in Swift?

Multiple inheritance is not possible in Swift.

How does Swift achieve multiple inheritance?

Swift doesn't allow us to declare a class with multiple base classes or superclasses, so there is no support for multiple inheritance of classes. A subclass can inherit just from one class. However, a class can conform to one or more protocols.

Is there inheritance in Swift?

The ability to take than more form is defined as Inheritance. Generally a class can inherit methods, properties and functionalities from another class. Classes can be further categorized in to sub class and super class.


1 Answers

super.foo() should be sufficient, since B prints "B" and calls super to print "A".

class C: B {
    override func foo() {
        super.foo()
        print("C")
    }
}

let c = C()
c.foo()

Output:

A
B
C

If you want to intentionally expose A's foo() from B, you need to create a new accessor:

class B: A {
    override func foo() {
        super.foo()
        print("B")
    }

    func exposeFoo() {
        super.foo()
    }
}

class C: B {
    override func foo() {
        super.exposeFoo()
        print("C")
    }
}

Or, use NSObject and the power of the Objective-C runtime:

class A: NSObject { // make sure your base class inherits from NSObject
    func foo() {
        print("A")
    }
}

// ...

class C: B {
    override func foo() {

        guard let superSuper = self.superclass?.superclass() else {
            return; // no super super
        }

        let fooImp = class_getMethodImplementation(superSuper, "foo")

        typealias MyCFunction = @convention(c) (AnyObject, Selector) -> Void
        let curriedImplementation = unsafeBitCast(fooImp, MyCFunction.self)
        curriedImplementation(self, selector) // prints A
    }
}
like image 147
JAL Avatar answered Nov 15 '22 08:11

JAL