Search code examples
iosswiftinheritancecomposition

Composition rather than inheritance for shared variables


I was previously using a class that could be simplfied down to this:

class Whatever {

  var someArray = [Int]()

  func unchangingFunction {
    print("test")
  }

  func functionForOverride() {}

}

I was asking of ways to improve this, and I got told to favour composition over inheritance, using something like the following:

protocol Implementation {
  func functionForOverride()
}

final class Whatever {

  var someArray = [Int]() // How can I access this?

  let implementation: Implementation

  init(implementation: Implementation) {
    self.implementation = implementation
  }

  func unchangingFunction() {
    print("test")
  }

  func functionForOverride() {
    implementation.functionForOverride()
  }

}

However, with this, I can't find a way to do anything with the someArray array:

struct Something: Implementation {

  func functionForOverride() {
    print(someArray) // This cannot work
  }

}

With the original code I am able to access and alter someArray however I want, but with this new way, I can't think of an easy solution.


Solution

  • If 'Implementation' requires 'someArray' to do what it is intended to do, then you should have 'Implementation' require any object conforming to it to also declare 'someArray'

    Like this:

    protocol Implementation {
        var someArray: [Int]
    }
    

    And if you know what you want to do with 'someFunction', then you could give a default implementation of it with a protocol extension like so:

    extension Implementation {
        func someFunction() {
            //you can do some stuff with someArray here
        }
    }
    

    Then when you conform to 'Implementation' you need to declare 'someArray' but not 'someFunction', unless you want to override the default function.

    E.g.

    class MyClass: Implementation {
         var someArray: [Int]!
    
         init() {}
    }
    

    Note that MyClass now has access to 'someFunction', which can be freely overridden in your class, and that you can add as many functions as you want to 'Implementation's extension.