Subclassing VS Extension in Swift

Class extension vs. subclassing in Swift?

It's

b)

because adding (stored) properties in a class extension is not supported.

There are two important rules for using extensions:

  • Extensions can add new functionality to a type, but they cannot override existing functionality

  • Extensions can add new computed properties, but they cannot add stored properties, or add property observers to existing properties

Subclassing vs Extension in swift

As a general rule of thumb (YMMV):

  • Are you adding general-purpose functionalities that should be available to every UITextField? If so, make an extension. All UITextField instances can call the new methods.
  • Are you adding functionality that should be restricted to special instances of UITextField that you would identify precisely? If so, make a subclass. Only the instances of the subclass can use the new methods.

There are other technical considerations, like extensions can't add fields, for instance.

Subclassing vs Extension vs Inner Class

In each of your previous examples, you are coupled to a hierarchy or placing all API related calls as extensions on a single class. This could make your code less flexible and harder to maintain. One solution that may work for you is to use dependency injection.

Here is an example of how you could structure your code.

struct QuizletAPICredentials {
var clientID: String
var accessCodes: [String]
//etc...
}

class QuizletSetClient {
var credentials: QuizletAPICredentials

init(credentials: QuizletAPICredentials) {
self.credentials = credentials
}

func fetchSets( ... ) {
//get data...
}
}

I hope this helps! :-]

Difference between adopting protocol+extension VS using instance of a class

There are a couple of approaches when you want to add this foo functionality to multiple UIViewController (or what have you) subclasses:

  1. The protocol approach with extensions:

    The problem is that while this works great with Swift-only code, it doesn't work so well when you're writing code that must be called by Cocoa directly.

    The merit of this approach (when you can) is that you start to enjoy the advantages outlined in WWDC 2015 Protocol-Oriented Programming in Swift.

  2. The component approach (where you have some Controller instance that your view controllers can vend):

    This is great when you need shared functionality that will be integrating directly with Cocoa. For example, this can be used when doing custom view controller transitions and don't want to repeat code in the various view controllers. This approach can be a manifestation of the single responsibility principle and can help fight view controller bloat.

For the sake of completeness, there are a few more options to achieve reuse:


  1. As matt suggested, you can also implement foo as an extension to some shared base class.

    This works great when the routine makes sense for not just your two existing subclasses, but all subclasses. But this is not appropriate if this is functionality unique to just those two particular subclasses.

  2. You can also put foo into a subclass of that base class (e.g. FooViewController subclasses UIViewController), and then have your two previous subclasses then subclass that new FooViewController class.

    This addresses the indiscriminate nature of a simple extension of the base class.

    The problem is that this is not as flexible as the first two approaches (e.g. no multiple inheritance, one set of Fooable methods and another set of Barable methods).

Bottom line, the right approach depends up the specific problem you're trying to solve. Your example is too generic for us to offer specific counsel.

Swift extension for all subclasses of a class

Unfortunately, you cannot override methods in the superclass HumanMother in a generic way... yet.. which I personally find to be quite annoying. Class hierarchies and extensions don't work as well together in swift as this cool example may lead-on to be.

If you want to define a method (not an override) for all subclasses, this will work:

First define a protocol:

protocol BigMamma {
func damnGirl()
}

Then define it for subclasses of "HumanMother" types.

extension BigMamma where Self: HumanMother {
func damnGirl() {
print("Yeah Boi")
}
}

Ref: https://www.vadimbulavin.com/multiple-inheritance-swift/



Related Topics



Leave a reply



Submit