This is in reference to:

 swift-evolution/nnnn-overridable-members-in-extensions.md at 
overridable-members-in-extensions · jrose-apple/swift-evolution · GitHub 
<https://github.com/jrose-apple/swift-evolution/blob/overridable-members-in-extensions/proposals/nnnn-overridable-members-in-extensions.md>

The limitation of not being able to override methods introduced by an extension 
to a parent class within a child class is pretty significant and I would 
propose that we find and explore a way to allow such while supporting the 
original intent of this limitation.

This has become a problem for a project I’m working on when transitioning to 
Swift 4. Here is a description of the problem:

Our major application has a class hierarchy of financial transaction types 
similar to the following:

Transaction
Billable
        Taxable
                Purchase
                        Bill
                        ...
                Sales
                        Estimate
                        Invoice
                        ...
Deposit
Journal Entry
...

Etc.

These are currently implemented in ObjC but have been extended in Swift. So 
there are the original transaction classes in ObjC with extensions in Swift. 

This combination of ObjC/Swift has been done to support modern presentation in 
iOS, essentially following the MVVM approach. ‘Transaction’ has been extended 
and specifies the various View Model methods each of its child classes must 
implement. There are default implementations going down the Swift inheritance 
tree but each child can customize (override) those methods and, many times, 
calls the inherited method.

For instance, the header presentation for each transaction shows a date and 
total amount but each subclass has other header elements to show: all 
‘Billable’ transactions show a name and due date. Going down the chain, each 
final child class provides the explicit title to be shown in the header, such 
as ‘Invoice’. Further, the background color of the header is set based on the 
status of the transaction. Of course, some transactions only have one state, 
the default state provided by a parent class.

With this said, eliminating the ability to extend ‘Transaction’ and then 
override down in each subclass’s extension was very convenient. Under the 
current Swift 4 restrictions we will have to either reimplement the class 
extensions in the original model (which will not be done because the model must 
be ignorant of any presentation-specific requirements) or everything will have 
to be moved up into a single Transaction extension and use a switch structure 
based on dynamic casting as discussed in the article mentioned way above (which 
corrupts ‘Transaction’ by requiring it to know intimate details about its 
children, grandchildren, etc.).

It would be nice if there were some protocol-based mechanism where a parent 
class could adopt that protocol (not in the original class declaration, of 
course, since UI-related methods should not be polluting the model layer) and 
then some extension-like mechanism allowing child classes to provide their 
specific implementation of those methods.

Of course, one potential approach would be to create a similar class structure 
to the model’s Transaction structure but where the new class ‘owns’ the 
instance of the raw transaction. Say, something like TransactionVM with 
BillableVM, PurchaseVM, etc. Of course, for each different type of transaction 
presentation (full details, brief details, list summary, etc.) there would need 
to be yet another ‘container’ class structure. And they wouldn’t be able to 
inherit from one another for the same reason I’m blathering on here.

Of course, if there is already a more appropriate approach for solving a 
problem like this, please do not hesitate to correct me as I still consider 
myself pretty ‘young’ with Swift 4.

Mike

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to