Returning a subclass from its base class in swift

I am trying to allow a method in a super class to return an instance of the subclass so that I can use method chaining with methods across both the parent and the child.

However, I am getting the error “BaseClass does not have a member named someOtherChainableMethod” when I attempt to chain the methods. Here is my code:

  • How do I access program arguments in Swift?
  • Swift override protocol methods in sub classes
  • Swift mask of circle layer over UIView
  • Parsing JSON array to Server with Swift 3.0
  • NSURLSession delegates not called
  • ADMOB Memory Leaking?
  • class BaseClass {
        func someChainableMethod() -> BaseClass {
            return self
        }
    }
    
    class ChildClass: BaseClass {
        func someOtherChainableMethod() -> ChildClass {
            return self
        }
    }
    
    let childClass = ChildClass
    
    childClass.someChainableMethod().someOtherChainableMethoid()
    

    The issue seems to be that the ‘return self’ in the parent chain-able method is returning an instance with type BaseClass rather than ChildClass.

    I have also tried this with generics and failed, this is what I tried:

    class BaseClass<T> {
        func someChainableMethod() -> T {
            return self
        }
    }
    
    class ChildClass: BaseClass<ChildClass> {
        func someOtherChainableMethod() -> ChildClass {
            return self
        }
    }
    
    let childClass = ChildClass
    
    childClass.someChainableMethod().someOtherChainableMethoid()
    

    In this case the error from the BaseClass someChainableMethod method, is “BaseClass is not convertible to T”.

    4 Solutions Collect From Internet About “Returning a subclass from its base class in swift”

    Your code works if you change the return type of the methods to Self:

    class BaseClass {
        func someChainableMethod() -> Self {
            return self
        }
    }
    
    class ChildClass: BaseClass {
        func someOtherChainableMethod() -> Self {
            return self
        }
    }
    
    let childClass = ChildClass()
    let foo = childClass.someChainableMethod().someOtherChainableMethod()
    

    Add someOtherChaingableMethod in your base class and left a empty implementation.

    Since you already know that childClass is an instance of ChildClass, you can do

    (childClass.someChainableMethod() as ChildClass).someOtherChainableMethoid()
    

    Simply override the base class someChainableMethod

    class BaseClass {
        func someChainableMethod() -> Self{
            return self
        }
    }
    
    class ChildClass: BaseClass {
        override func someChainableMethod() -> Self {
            return self
        }
        func A(){
    
        }
    }
    
    var objChild = ChildClass()
    objChild.someChainableMethod()